Search code examples
c#azure-functionssystem.text.jsonazure-functions-isolated

.NET 8 Azure Functions: setting System.Text.JsonSerializer defaults


I'm trying to set a convertor to be used on every request to an Azure Function using a JsonResult.

I'm using the new VS2022 templates for azure functions using .NET 8. This means: the extension ConfigureFunctionsWebApplication is used and not the older ConfigureFunctionWorker.

I'm trying to set the options as it seems to be used in https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.Core/src/Infrastructure/SystemTextJsonResultExecutor.cs#L26

but it isn't working.

.ConfigureFunctionsWebApplication((hostBuilderContext, functionsWorkerApplicationBuilder) =>
    {
        functionsWorkerApplicationBuilder.Services.Configure<JsonOptions>(options =>
        {
            options.SerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
            options.SerializerOptions.Converters.Add(new JsonStringEnumConverter());
            options.SerializerOptions.PropertyNameCaseInsensitive = true;
            #if DEBUG
            options.SerializerOptions.WriteIndented = true;
            #endif
        });
    }

does absolutely nothing.

I can get it working if I replace it with a call like:

functionsWorkerApplicationBuilder.Services.AddMvcCore().AddJsonOptions(options => options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()));

But that might drag in a lot of stuff I don't want or need.

Does anyone know the proper way to set the jsonserialization defaults?

And please don't answer with answers that are valid for older .NET version or Newtonsoft. Especially newtonsoft seems to be on the way out of the framework.

edit:

I appreciate people looking over my question, but I explicitly asked for an answer pertaining to the latest way of building Azure Functions as advertised by Microsoft. https://learn.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide?tabs=windows#http-trigger So not the build in classes HttpRequestData and HttpResponseData, but the classes OkObjectResult en JsonResult that come from the new mvc core integration. These seem to be the current way forward.


Solution

  • I finally figured out the problem. There is Microsoft.AspNetCore.Http.Json.JsonOptions and there is Microsoft.AspNetCore.Mvc.JsonOptions.

    JsonResult which works with IActionResultExecutor uses Microsoft.AspNetCore.Mvc.JsonOptions.

    So this will work:

            services.Configure<Microsoft.AspNetCore.Mvc.JsonOptions>(options =>
            {
                options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
                options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
                options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
            });
    

    But this won't:

            services.Configure<Microsoft.AspNetCore.Http.Json.JsonOptions>(options =>
            {
                options.SerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
                options.SerializerOptions.Converters.Add(new JsonStringEnumConverter());
                options.SerializerOptions.PropertyNameCaseInsensitive = true;
           });
    

    This cost me hours. Wish microsoft didn't reuse classnames so blatently