Search code examples
json.net.net-7.0output-formatting

NewtonsoftJsonOutputFormatter Customized but it wont work


I have a custom output formatter like below:

public class WrappedJsonOutputFormatter : NewtonsoftJsonOutputFormatter
{
    public ApiVersion Version { get; set; }

    public WrappedJsonOutputFormatter(JsonSerializerSettings serializerSettings, ArrayPool<char> charPool, MvcOptions options, MvcNewtonsoftJsonOptions? jsonOptions)
        : base(serializerSettings, charPool, options, jsonOptions)
    {
    }

    public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
    {
        if (context.HttpContext.Response.StatusCode == (int)HttpStatusCode.OK)
        {
            var @object = new ApiResponse { Data = context.Object, ApiVersion = context.HttpContext?.GetRequestedApiVersion()?.ToString() ?? "1.0", StatusCode = context.HttpContext.Response.StatusCode };

            var newContext = new OutputFormatterWriteContext(context.HttpContext, context.WriterFactory, typeof(ApiResponse), @object)
            {
                ContentType = context.ContentType,
                ContentTypeIsServerDefined = context.ContentTypeIsServerDefined
            };

            TimeSpan responseTime = DateTime.Now - (DateTime)context.HttpContext.Items["RequestTime"];
            @object.ResponseTime = responseTime.TotalMilliseconds;
            newContext.HttpContext.Response.Headers.Add(ResponseTimeMiddleware.RESPONSE_HEADER_RESPONSE_TIME, responseTime.TotalMilliseconds.ToString("0.00"));

            return base.WriteResponseBodyAsync(newContext, selectedEncoding);
        }

        return base.WriteResponseBodyAsync(context, selectedEncoding);
    }
}

And my program.cs output settings like this:

builder.Services.AddControllers(options =>
            {                    
                jsonSettings.Converters.Add(new StringEnumConverter());
                var formatter = options.InputFormatters.OfType<SystemTextJsonInputFormatter>().Single();

                formatter.SerializerOptions.Converters.Add(new JsonStringEnumConverter());
                formatter.SerializerOptions.ReadCommentHandling = System.Text.Json.JsonCommentHandling.Skip;
                formatter.SerializerOptions.AllowTrailingCommas = true;

                options.OutputFormatters.RemoveType<SystemTextJsonOutputFormatter>();
                options.OutputFormatters.Add(new WrappedJsonOutputFormatter(jsonSettings, ArrayPool<char>.Shared, options, null));
            });

When i call api on swagger it works.

Swagger SS

But when i call axios or directly browser it won't work.

Browser ss

Why happens theese differences? And how can i solve them?


Solution

  • i solve this problem change my code like this:

    builder.Services.AddControllers(options =>
                {
                    jsonSettings.Converters.Add(new StringEnumConverter());
                    var formatter = options.InputFormatters.OfType<SystemTextJsonInputFormatter>().Single();
    
                    formatter.SerializerOptions.Converters.Add(new JsonStringEnumConverter());
                    formatter.SerializerOptions.ReadCommentHandling = System.Text.Json.JsonCommentHandling.Skip;
                    formatter.SerializerOptions.AllowTrailingCommas = true;
    
                    while (options.OutputFormatters.Count > 0)
                    {
                        options.OutputFormatters.RemoveAt(0);
                    }
                    
                    options.OutputFormatters.Add(new WrappedJsonOutputFormatter(jsonSettings, ArrayPool<char>.Shared, options, null));
                });
    

    By that i ensure there is only one formatter in application.