当我们在开发.NET Core API时,有时候需要在API返回结果中自定义格式,比如JSON格式化、XML格式化或者自定义格式化等。这时我们可以使用OutputFormatter来自定义输出格式,本文将详细讲解OutputFormatter的使用方法。
什么是OutputFormatter
OutputFormatter是.NET Core框架中提供的一个类,它用于在API返回结果中自定义输出格式。通过继承OutputFormatter类并重写其中的方法,我们可以自定义各种格式化输出。
OutputFormatter的基本使用
OutputFormatter是抽象类,不能直接实例化。我们需要创建一个继承OutputFormatter的类,并在其中实现自定义格式化的逻辑。下面是一个示例:
public class MyOutputFormatter : OutputFormatter
{
private readonly string mediaType;
public MyOutputFormatter(string mediaType)
{
if (string.IsNullOrEmpty(mediaType))
{
throw new ArgumentNullException(nameof(mediaType));
}
this.mediaType = mediaType;
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse(mediaType));
}
protected override bool CanWriteType(Type type)
{
return true;
}
public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
{
// 格式化输出逻辑
await context.HttpContext.Response.WriteAsync($"Hello from {mediaType}");
}
}
其中:
- 构造函数中通过添加 mediaType 来设置输出格式的媒体类型。
- 重写 CanWriteType 方法,返回 true 表示这个输出格式支持所有类型。
- 重写 WriteResponseBodyAsync 方法,完成格式化输出逻辑。在这个方法中,我们可以通过 context 参数获取要输出的对象,通过 selectedEncoding 参数获取编码方式,然后格式化输出。
完成自定义OutputFormatter后,我们需要在Startup.cs文件中注册它。可以通过以下方式进行注册:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(opts =>
{
opts.OutputFormatters.Insert(0, new MyOutputFormatter("application/myformat"));
});
}
OutputFormatter示例
下面通过两个示例,说明OutputFormatter的具体使用方法。
示例一:自定义JSON格式输出
ASP.NET Core默认的JSON输出格式是驼峰式命名。有时我们需要将输出的属性名称转换为大写格式。这时我们可以通过自定义OutputFormatter来实现。
// 定义输出格式
public class UpperCaseNamingPolicy : JsonNamingPolicy
{
public override string ConvertName(string name) => name.ToUpper();
}
// 定义OutputFormatter
public class UpperCaseNamingPolicyFormatter : SystemTextJsonOutputFormatter
{
public UpperCaseNamingPolicyFormatter(JsonSerializerOptions options) : base(options)
{
}
public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding encoding)
{
var response = context.HttpContext.Response;
response.ContentType = "application/json";
response.StatusCode = 200;
var json = JsonSerializer.Serialize(context.Object, _jsonOptions);
json = json.ToJson(ConfigurationManager.AppSettings["ConvertDataType"].ToString().Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)); // 可以在这里对输出对象进行二次处理
using (var writer = new StreamWriter(response.Body, encoding))
{
await writer.WriteAsync(json.TrimEnd('\r','\n'));
await writer.FlushAsync();
}
}
}
在该类的构造函数中,对JSON序列化组件进行了设置,以保证格式处理的正确性。在WriteResponseBodyAsync方法中,我们将输出对象格式化为JSON格式,并将属性名称转换为大写格式。在进行对象的序列化处理后,我们也可以对输出对象进行二次处理。
最后,在Startup.cs文件中进行注册:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
// 添加自定义输出格式
services.AddSingleton<JsonSerializerOptions>(new JsonSerializerOptions
{
PropertyNamingPolicy = new UpperCaseNamingPolicy(),
WriteIndented = true
});
services.AddMvc(options =>
{
options.OutputFormatters.RemoveType<SystemTextJsonOutputFormatter>();
options.OutputFormatters.Insert(0, new UpperCaseNamingPolicyFormatter(options));
});
}
示例二:自定义CSV格式输出
有时我们需要将API返回的数据以CSV格式进行输出。这时可以通过自定义OutputFormatter来实现。
// 定义输出格式
public class CsvMediaType : MediaTypeHeaderValue
{
public CsvMediaType() : base("text/csv")
{
}
}
// 定义OutputFormatter
public class CsvOutputFormatter : OutputFormatter
{
CsvMediaType csvMediaType;
public CsvOutputFormatter(CsvMediaType csvMediaType)
{
this.csvMediaType = csvMediaType;
SupportedMediaTypes.Add(csvMediaType);
}
protected override bool CanWriteType(Type type)
{
return typeof(IEnumerable<ExpandoObject>).IsAssignableFrom(type);
}
public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
{
var response = context.HttpContext.Response;
response.Headers.Add("Content-Disposition", new ContentDispositionHeaderValue("attachment")
{
FileName = "export.csv"
}.ToString());
response.ContentType = csvMediaType.ToString();
var streamWriter = new StreamWriter(response.Body, selectedEncoding);
var csvWriter = new CsvWriter(streamWriter, CultureInfo.CurrentCulture);
var records = (IEnumerable<ExpandoObject>)context.Object;
// 写入列名
var columnNames = ((IDictionary<string, object>)records.First()).Keys.ToList();
foreach (var columnName in columnNames)
{
csvWriter.WriteField(columnName);
}
csvWriter.NextRecord();
// 写入数据
foreach (var record in records)
{
foreach (var columnName in columnNames)
{
csvWriter.WriteField(((IDictionary<string, object>)record)[columnName]?.ToString());
}
csvWriter.NextRecord();
}
return Task.CompletedTask;
}
}
其中,CsvMediaType类用于定义媒体类型为CSV,CsvOutputFormatter类用于自定义CSV格式输出。在CanWriteType方法中,我们通过判断输出对象是否为IEnumerable
最后,在Startup.cs文件中进行注册:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(opts =>
{
opts.OutputFormatters.Insert(0, new CsvOutputFormatter(new CsvMediaType()));
});
}
这样,每次API返回IEnumerable
通过以上两个示例,我们可以发现OutputFormatter的强大之处。我们可以根据具体业务需要,自定义各种格式化输出,提高API返回结果的灵活性。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:.NET Core API之格式化输出对象OutputFormatter - Python技术站