Search code examples
c#azure-functions.net-6.0system.text.jsonjson-serialization

Specifying JsonSerializerOptions in .NET 6 isolated Azure Function


I'm trying to call a Web API from code in an Azure Function that I've just ported to .NET 6 (isolated hosting model). I took the chance of the migration to get rid of the RestSharp and Json.NET dependencies, now only just using HttpClient and System.Text.Json for handling the HTTP calls and JSON stuff.

I did try to use this code which seemed like the perfect combo:

Project project = await _httpClient.GetFromJsonAsync<Project>(someUrl);

if (project != null)
{
    HttpResponseData callResponse = req.CreateResponse(HttpStatusCode.OK);
    
    await callResponse.WriteAsJsonAsync(project);
    
    return callResponse;
}

The call works fine - I get back my Project object without any hitch.

But unfortunately, with this code, I cannot seem to influence the way the JSON in the response gets rendered - e.g. in my case, null values are returned (which I want to avoid), and all property names are capitalized ("Institute", instead of "institute", "LeadLanguage" instead of "leadLanguage").

No problem - just use a JsonSerializerOptions object and define what you want, I thought. Sure, I can create such an object - but where would I plug that in??

WriteAsJsonAsync doesn't seem to support any serializer options as parameter (why??), and I couldn't find a way to globally define my JsonSerializerOptions (since everything I find seems to be based on the services.AddControllers().AddJsonOptions() method - which I cannot use since my Azure Function doesn't have the AddControllers part in its startup code).

I have managed to get the results I want by doing this:

if (project != null)
{
    HttpResponseData callResponse = req.CreateResponse(HttpStatusCode.OK);
    
    callResponse.Headers.Add("Content-Type", "application/json");
    string jsonResponse = JsonSerializer.Serialize(project, settings);
    await callResponse.WriteStringAsync(jsonResponse, Encoding.UTF8);

    return callResponse;
}

but that seems a bit convoluted and "low-level" - manually converting the result object into string, having to manually set the Content-Type and all ....

Is there really no way in an Azure Function (.NET 6 isolated hosting model) to globally specify JsonSerializerOptions - or call WriteAsJsonAsync with a specific serializer options object?


Solution

  • And 10 seconds after I posted the question - of course! - I ran across the way to do it with an Azure Function.

    Something like this:

    var host = new HostBuilder()
        .ConfigureFunctionsWorkerDefaults()
        .ConfigureServices(s =>
        {
            s.AddHttpClient();
            // define your global custom JSON serializer options
            s.Configure<JsonSerializerOptions>(options =>
            {
                options.AllowTrailingCommas = true;
                options.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
                options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
                options.PropertyNameCaseInsensitive = true;
            });
    

    Hope that might help someone else down the line!