3

I want to use different formats for DateTime fields regarding query string parameter: i.e if query string contains dateFormat=iso parameter, I want to return dates in ISO 6801:

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

But if query string contains dateFormat=unix parameter, I want to return dates in UNIX time:

{
  "date": 1522152517
}

It is pretty easy to achieve using JsonResult and ResultFilter:

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();
    }
}

I don't want to scramble the global JsonSerializerSettings, so I resolve IOptionsSnapshot<MvcJsonOptions> instead of IOptions<MvcJsonOptions>.

But how can I achieve this behavior for ObjectResult?

McGuireV10
  • 9,572
  • 5
  • 48
  • 64
Sane
  • 2,334
  • 2
  • 17
  • 20
  • 1
    Is this what you want? [ASP.NET Core API JSON serializersettings per request](https://stackoverflow.com/q/44828302/3744182). – dbc Mar 27 '18 at 22:32
  • I want to change json serialization in JsonOutputFormatter as well, but JsonOutputFormatter is used in JsonHelper and etc, so I want change it only for particular requests. – Sane Mar 28 '18 at 08:11

1 Answers1

1

As for ObjectReault you can create a new ObjectResult with new JsonOutputFilter with required 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;
}
Sane
  • 2,334
  • 2
  • 17
  • 20