Chris Peters
Chris Peters

Reputation: 41

.net core 2.1 - AddJsonOptions not working

In my .net core 2.1 web app(WebApi + SPA) I am having problems with the API not correctly handling JSON:

My startup.cs > configureservices looks like:

public void ConfigureServices(IServiceCollection services)
        {

            var connectionString = Configuration.GetConnectionString("AppContext");
            services.AddEntityFrameworkNpgsql().AddDbContext<AppContext>(options => options.UseNpgsql(connectionString));

            services.AddScoped<ISCTMRepository, SCTMRepository>();

            services.AddMvc()
                .AddJsonOptions(options =>
                {
                    options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
                    options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                });

            services.AddSpaStaticFiles(configuration =>
            {
                configuration.RootPath = "ClientApp/dist";
            });
        }

I've tried updating my controller action to the following:

[HttpGet, Route("")]
public async Task<IActionResult> GetLocations()
{
    var _data = await _repo.GetLocations();

    var json = JsonConvert.SerializeObject(_data, 
            new JsonSerializerSettings {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            });
    return Ok(json);
}

And this does indeed fix both issues - but I'm not able to figure out why the global setting in startup is being ignored.

Upvotes: 1

Views: 2147

Answers (1)

kennyzx
kennyzx

Reputation: 12993

It is because the serialization is not done by the framework, it is done by the call JsonConvert.SerializeObject, which does not respect the configuration you specify in Startup.cs - it does respect the JsonSerializerSettings you pass as a parameter.

If you write the API like this, you can see the configuration in Startup.cs takes effect.

[HttpGet, Route("")]
public async Task<IActionResult> GetLocations()
{
    var _data = await _repo.GetLocations();
    return new OkObjectResult(_data);  //Let the framework serialize this object 
}

By the way, ASP.NET Core is by default using camel-casing in serialization, you don't really need to configure it explicitly. Just replace the line JsonConvert.SerializeObject.

Upvotes: 4

Related Questions