简体   繁体   中英

AspNet Core - input/output JSON serialization settings at Controller Level

My application requires the (almost default) JSON serialization settings:

services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .AddJsonOptions(options =>
            {
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                options.SerializerSettings.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
                options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
            });

For one controller only, I need to use a different naming strategy for both input (where I use model binding with [FromBody] myComplexObject and output with

options.SerializerSettings.ContractResolver = new DefaultContractResolver();

My question is virtually identical to Web API: Configure JSON serializer settings on action or controller level with the exception that I'm asking for AspNet Core 2.2+, in which IControllerConfiguration is no longer existent.

The Core 2.1+ equivalent question has a response here: Configure input/output formatters on controllers with ASP.NET Core 2.1

The answers there appear slightly fragmented or incomplete - it's hard to imagine that there is no easier way to achieve this. Would anyone have an idea on how to use a DefaultContractResolver for all input and output within a single controller?

The answer you link works well enough, but you can extend it further by wrapping it in an attribute that you can apply to any action or controller. For example:

public class JsonConfigFilterAttribute : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext context)
    {
        if (context.Result is ObjectResult objectResult)
        {
            var serializerSettings = new JsonSerializerSettings
            {
                ContractResolver = new DefaultContractResolver()
            };

            var jsonFormatter = new JsonOutputFormatter(
                serializerSettings, 
                ArrayPool<char>.Shared);

            objectResult.Formatters.Add(jsonFormatter);
        }

        base.OnResultExecuting(context);
    }
}

And just add it to action methods or controllers:

[JsonConfigFilter]
public ActionResult<Foo> SomeAction()
{
    return new Foo
    {
        Bar = "hello"
    };
}

For Global Setting in Startup.cs, having installed Newtonsoft.json, you will have this

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());

For Individual Controller, you can override the global setting below

 public JsonResult GetStates()
    {
        var model = new List<StateObject>();
        if (!string.IsNullOrEmpty(id))
        {
            var schedule = _settingsService.GetStates().ToList();
            return Json(new SelectList(schedule, "StateCode", "Name"), new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver() });
        }
        else
            return Json(new SelectList(model, "StateCode", "Name"), new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver() });
    }

Let me know if this solves your problem, or you need further Assitance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM