13

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?

2 Answers 2

34

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!

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for the answer, @marc_s! Just a heads up for people that may have issues with specific properties convertion - in my case I had an YouTubeVideoId that got converted to you_tube_video_id (w/ an underscore between you and tube). In this case I decorated the property with [JsonPropertyName("youtube_video_id")] so it got converted as I expected: youtube_video_id
The difference between the answers from Kaptein Babbalas and marc_s is that the Kaptein replaces the serializer ánd the serializationoptions. marc_s sets specific options. The Kaptein's method might have unexpected side effects. E.g. case sensitivity is turned on in a newed options object. It is off in the default functions configuration
4

Can also be done in the ConfigureFunctionsWorkerDefaults

  var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults(builder =>
{
    builder.Serializer = new JsonObjectSerializer(new JsonSerializerOptions
    {
        AllowTrailingCommas = true,
        .....
    });
}) .ConfigureServices((context, services) =>{.....}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.