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

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了客户要求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的封装

结论

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

使用x-format Header

不使用x-format Header

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

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

以上是关于客户要求ASP.NET Core API返回特定格式,怎么办?(续)的主要内容,如果未能解决你的问题,请参考以下文章

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

ASP.NET Core API 在从 React 客户端调用时返回 401

使用ETag协议实现ASP.NET Core API缓存

Blazor ASP.Net Core 3.1 Web API 在发布时返回 404 错误

ASP.NET Core Refit Client for RESTful API:如何划分客户端

ASP.NET Core MVC 使用 api +javascript 客户端与 ajax