如何在每个请求上更改JsonSerializerSettings

时间:2018-03-27 12:35:01

标签: c# asp.net-core json.net

我想对查询字符串参数的DateTime字段使用不同的格式:即如果查询字符串包含dateFormat=iso参数,我想在ISO 6801中返回日期:

{
  "date": "2018-03-27T12:20:34.248563Z"
}

但是如果查询字符串包含dateFormat=unix参数,我想在UNIX时间返回日期:

{
  "date": 1522152517
}

使用JsonResultResultFilter

很容易实现
public class DateFormatResultFilter : IAsyncResultFilter
{
    public async Task OnResultExecutionAsync(ResultExecutingContext context,ResultExecutionDelegate next)
    {
        var dateTimeFormat = context.HttpContext.Request.Query["dateFormat"].FirstOrDefault() ?? "iso8601";
        var converter = GetConverter(dateTimeFormat);

        var jsonSettings = context.HttpContext.RequestServices
            .GetRequiredService<IOptionsSnapshot<MvcJsonOptions>>()
            .Value.SerializerSettings;

        jsonSettings.Converters.Add(converter);

        if (context.Result is JsonResult jsonResult)
        {
            var value = jsonResult.Value;


            context.Result = new JsonResult(value, jsonSettings);
        }
        await next();
    }
}

我不想加扰全球JsonSerializerSettings,因此我解析IOptionsSnapshot<MvcJsonOptions>而不是IOptions<MvcJsonOptions>

但是如何才能为ObjectResult实现此行为?

1 个答案:

答案 0 :(得分:1)

对于ObjectReault,您可以使用新JsonOutputFilter创建一个新的ObjectResult,其中包含JsonSerializerSettings

var jsonSerializationSettings = ...;
if (context.Result is ObjectResult objectResult)
{
    var result = new ObjectResult(objectResult.Value)
    {
        ContentTypes = objectResult.ContentTypes,
        DeclaredType = objectResult.DeclaredType,
        StatusCode = objectResult.StatusCode,
        Formatters = new FormatterCollection<IOutputFormatter>(objectResult.Formatters)
    };
    result.Formatters.RemoveType<JsonOutputFormatter>();
    result.Formatters.Add(new JsonOutputFormatter(jsonSerializationSettings, ArrayPool<char>.Shared));
    context.Result = result;
}