Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 699
ExternalUse Avatar asked May 14 '19 09:05

ExternalUse


2 Answers

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"
    };
}
like image 107
DavidG Avatar answered Sep 21 '22 06:09

DavidG


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.

like image 37
Samuel Akosile Avatar answered Sep 23 '22 06:09

Samuel Akosile