ASP.Net Core-客户格式化程序优先

时间:2019-01-24 14:17:17

标签: c# asp.net-core asp.net-core-webapi

我遵循示例here,并在下面编写了客户格式化程序。它可以正常工作,但是问题是它始终首先运行,并且没有考虑到仅当Accept Header是text / csv时才应该运行。

public class CSVFormatter : TextOutputFormatter
{
    private string FileName { get; set; }

    public CSVFormatter()
    {
        SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/csv"));

        SupportedEncodings.Add(Encoding.UTF8);
        SupportedEncodings.Add(Encoding.Unicode);
    }

    protected override bool CanWriteType(Type type)
    {
        return IsTypeOfIEnumerable(type);
    }

    private bool IsTypeOfIEnumerable(Type type)
    {
        foreach (Type interfaceType in type.GetInterfaces())
        {
            if (interfaceType == typeof(IEnumerable))
                return true;
        }

        return false;
    }

    public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
    {
        IServiceProvider serviceProvider = context.HttpContext.RequestServices;

        var response = context.HttpContext.Response;
        var buffer = new StringBuilder();
        var value = context.Object;
        var type = context.ObjectType;

        WriteData(type, value, buffer, response);

        return response.WriteAsync(buffer.ToString());
    }

    private void WriteData(Type type, object value, StringBuilder buffer, HttpResponse response)
    {
        //NOTE: We have check the type inside CanWriteType method. If request comes this far, the type is IEnumerable. We are safe.

        Type itemType = type.GetGenericArguments()[0];

        //Write out columns
        buffer.AppendLine(string.Join<string>(",", itemType.GetProperties().Select(x => x.Name.ToLower())));

        foreach (var obj in (IEnumerable<object>)value)
        {
            var vals = obj.GetType().GetProperties().Select(pi => new { Value = pi.GetValue(obj, null) });
            string valueLine = string.Empty;

            foreach (var val in vals)
            {
                var columnValue = val.Value;
                valueLine = string.Concat(valueLine, columnValue, ",");
            }

            valueLine = valueLine.Substring(0, valueLine.Length - 1);

            buffer.AppendLine(valueLine);
        }
    }
}

我这样将其添加到Starup.cs中:

 services.AddMvc(options =>
            {
                options.RespectBrowserAcceptHeader = true;
                options.OutputFormatters.Insert(0, new CSVFormatter());
            })

.asp中的Asp.net核心,我只在需要时才通过指定特定查询字符串“ format = csv ”来运行我的自定义格式化程序,例如

几个问题:

  • 如何强制它仅在需要时运行。
  • 我还可以在查询字符串或标头中传递文件名,并在自定义格式程序中读取它,然后像这样添加它。

headers.Add("Content-Disposition", string.Format("attachment; filename={0}", FileName));

0 个答案:

没有答案