8

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?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459

2 Answers2

22

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!

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
2

Can also be done in the ConfigureFunctionsWorkerDefaults

  var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults(builder =>
{
    builder.Serializer = new JsonObjectSerializer(new JsonSerializerOptions
    {
        AllowTrailingCommas = true,
        .....
    });
}) .ConfigureServices((context, services) =>{.....}
Kaptein Babbalas
  • 1,058
  • 12
  • 15