客戶要求ASP.NET Core API返回特定格式,怎麼辦?(續)
前言
上次,我們用
FormatFilter
解決了客戶的需求:
客戶就要求API的返回值屬性名必須是PascalCase(如UserName),但是這些API需要同時提供給內部系統使用,預設都是CamelCase(如userName)。
其實,返回的都是JSON格式,只是寫入屬性名的大小寫不一樣。
那麼,直接修改JSON格式化實現,應該也是可行的?!
問題
在
http://
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即可。