客户要求ASP.NET Core API返回特定格式,怎么办?(续)

前言

上次,我们用

客户就要求API的返回值属性名必须是PascalCase(如UserName),但是这些API需要同时提供给内部系统使用,默认都是CamelCase(如userName)。

其实,返回的都是JSON格式,只是写入属性名的大小写不一样。

那么,直接修改JSON格式化实现,应该也是可行的?!

问题

在ASP.NET Core 3.0或更高版本中,默认JSON格式化程序基于 System.Text.Json,可以配置Microsoft.AspNetCore.Mvc.JsonOptions.JsonSerializerOptions实现自定义功能。

比如,设置返回值属性名是PascalCase格式:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers()
            .AddJsonOptions(options => 
               options.JsonSerializerOptions.PropertyNamingPolicy = null);
}

但是,这种只能实现固定设置,不能满足不同请求返回不同格式的需求。

这时,我们可以利用Newtonsoft.Json实现更灵活的配置。

添加Newtonsoft.Json支持

引用nuget包Microsoft.AspNetCore.Mvc.NewtonsoftJson,并修改Startup.cs,代码如下:

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddControllers().AddNewtonsoftJson(options =>
    {
        options.SerializerSettings.ContractResolver = new MyCustomContractResolver();
    });
}

使用自定义类MyCustomContractResolver格式化JSON。

MyCustomContractResolver实现

MyCustomContractResolver实现代码如下:

public class MyCustomContractResolver : DefaultContractResolver {
    private CamelCaseNamingStrategy _camelCase = new CamelCaseNamingStrategy();
    public override JsonContract ResolveContract(Type type)
    {
        return CreateContract(type);
    }
    protected override string ResolvePropertyName(string propertyName)
    {
        if (GetFormat() == "json2")
        {
            return propertyName;
        }

        return _camelCase.GetPropertyName(propertyName, false);
    }

    private string GetFormat()
    {
        Microsoft.Extensions.Primitives.StringValues headerValues;

        if (AppContext.Current.Request.Headers.TryGetValue("x-format", out headerValues))
        {
            return headerValues.FirstOrDefault();
        }
        return "json";
    }
}
  • 默认的ResolveContract缓存了指定类型的格式化设置,以加快运行速度,不能满足不同请求对同一类型执行不同的格式化要求。因此,为演示方便,这里去掉了缓存,你也可以实现自定义缓存

  • GetFormat是判断当前请求格式化方式的自定义方法。为演示方便,这里判断的是x-format Header,你也可以改成其他方式,比如根据当前用户凭证进行判断

  • AppContext.Current是对当前请求的HttpContext的封装

结论

最后,分别发送请求,运行效果如下图:

f71b6bf24c8f90a03d3249d18afdcc66.png

使用x-format Header

36c06ca8e57033f6cdb090660a1ed120.png

不使用x-format Header

完全满足了要求,只需要客户在每个API请求加上x-format Header即可。

如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“,记住我!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值