我遵循示例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));