客户要求ASP.NET Core API返回特定格式,怎么办?
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了客户要求ASP.NET Core API返回特定格式,怎么办?相关的知识,希望对你有一定的参考价值。
当ASP.NET Core API提供给到外部系统使用时,在某些情况下,可能需要根据这些外部系统的要求来格式化数据。
比如,客户就要求API的返回值属性名必须是PascalCase(如UserName),但是这些API需要同时提供给内部系统使用,默认都是CamelCase(如userName)。
怎么办?
虽然可以为外部系统重新做一套API,但是代价太大!能不能从自定义API的返回值上想办法?
在微软官方文档上找到一篇设置 ASP.NET Core Web API 中响应数据的格式[1],介绍了响应格式 URL 映射。
使用FormatFilter
可以根据请求路径的路由映射将相应映射到相应的格式上。
希望达到的效果:
[ApiController]
[Route("[controller]")]
[FormatFilter]
public class WeatherForecastController : ControllerBase
{
[HttpGet("{format?}")]
public IEnumerable<WeatherForecast> Get()
路由 | 响应格式 |
---|---|
WeatherForecast | 默认格式CamelCase |
WeatherForecast?format=json2 | PascalCase |
代码实现
首先,需要让API支持自定义格式,返回MediaType还是application/json
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(options =>
{
options.FormatterMappings.SetMediaTypeMappingForFormat
("json2", MediaTypeHeaderValue.Parse("application/json"));
});
}
接着,我们需要替换掉默认的Json OutputFomatter:
for (int i = 0; i < options.OutputFormatters.Count; i++)
{
if (options.OutputFormatters[i] is Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter jsonOutputFormatter)
{
options.OutputFormatters[i] = new CustomJsonOutputFormatter(jsonOutputFormatter.SerializerOptions);
break;
}
}
CustomJsonOutputFormatter的代码如下:
public class CustomJsonOutputFormatter : SystemTextJsonOutputFormatter
{
private readonly SystemTextJsonOutputFormatter pascalCaseFormater;
public CustomJsonOutputFormatter(JsonSerializerOptions jsonSerializerOptions) : base(jsonSerializerOptions)
{
var newOptions = new JsonSerializerOptions(jsonSerializerOptions);
newOptions.PropertyNamingPolicy = null;
pascalCaseFormater = new SystemTextJsonOutputFormatter(newOptions);
}
public override Task WriteAsync(OutputFormatterWriteContext context)
{
if (GetFormat(context) == "json2")
{
return pascalCaseFormater.WriteAsync(context);
}
return base.WriteAsync(context);
}
private string? GetFormat(OutputFormatterWriteContext context)
{
if (context.HttpContext.Request.RouteValues.TryGetValue("format", out var obj))
{
var routeValue = Convert.ToString(obj, CultureInfo.InvariantCulture);
return string.IsNullOrEmpty(routeValue) ? null : routeValue;
}
var query = context.HttpContext.Request.Query["format"];
if (query.Count > 0)
{
return query.ToString();
}
return "json";
}
}
如果format是json2
,就用pascalCaseFormater处理,否则使用默认处理。
小插曲: 需要设置pascalCaseFormater的JsonSerializerOptions.PropertyNamingPolicy属性,指定用于将对象的属性名称转换为其他格式(例如PascalCase)的策略,本来还准备实现一个PascalCasePolicy
。但是转念一想,C#本身的Property名不就是PascalCase的吗?!直接将PropertyNamingPolicy设为null不处理就行了。
结论
最后,运行结果如下:
完全满足了要求,只需要客户在每个API请求URL上加上?format=json2
即可。
如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“,记住我!
参考资料
[1]
设置 ASP.NET Core Web API 中响应数据的格式: https://docs.microsoft.com/zh-cn/aspnet/core/web-api/advanced/formatting?view=aspnetcore-5.0
以上是关于客户要求ASP.NET Core API返回特定格式,怎么办?的主要内容,如果未能解决你的问题,请参考以下文章
客户要求ASP.NET Core API返回特定格式,怎么办?(续)
ASP.NET Core API 在从 React 客户端调用时返回 401
Blazor ASP.Net Core 3.1 Web API 在发布时返回 404 错误