在 Rick Strahl 的 blog post 关于创建 JSONP 媒体类型格式化程序的一些帮助下,我提出了一个解决方案,允许 API 根据客户端请求从 camelCase 动态切换到 PascalCase。
创建一个派生自默认 JsonMediaTypeFormatter 并覆盖 GetPerRequestFormatterInstance 方法的 MediaTypeFormatter。您可以在此处实现您的逻辑以根据请求设置序列化程序设置。
public class JsonPropertyCaseFormatter : JsonMediaTypeFormatter
{
private readonly JsonSerializerSettings globalSerializerSettings;
public JsonPropertyCaseFormatter(JsonSerializerSettings globalSerializerSettings)
{
this.globalSerializerSettings = globalSerializerSettings;
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript"));
}
public override MediaTypeFormatter GetPerRequestFormatterInstance(
Type type,
HttpRequestMessage request,
MediaTypeHeaderValue mediaType)
{
var formatter = new JsonMediaTypeFormatter
{
SerializerSettings = globalSerializerSettings
};
IEnumerable<string> values;
var result = request.Headers.TryGetValues("X-JsonResponseCase", out values)
? values.First()
: "Pascal";
formatter.SerializerSettings.ContractResolver =
result.Equals("Camel", StringComparison.InvariantCultureIgnoreCase)
? new CamelCasePropertyNamesContractResolver()
: new DefaultContractResolver();
return formatter;
}
}
请注意,我将 JsonSerializerSettings 参数作为构造函数参数,以便我们可以继续使用 WebApiConfig 来设置我们想要使用的任何其他 json 设置,并让它们仍然应用在这里。
然后在您的 WebApiConfig 中注册此格式化程序:
config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new StringEnumConverter());
config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
config.Formatters.JsonFormatter.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
config.Formatters.Insert(0,
new JsonPropertyCaseFormatter(config.Formatters.JsonFormatter.SerializerSettings));
现在,标头值为 X-JsonResponseCase: Camel 的请求将在响应中收到驼峰式属性名称。显然,您可以更改该逻辑以使用您喜欢的任何标题或查询字符串参数。