'Setting defaults for JsonContent in Asp.Net Core

I'm trying to send a POST request with multipart form data (a file and a Json field) in Asp.Net Core 6.0. The relevant part of the code is

...

using var request = new HttpRequestMessage(HttpMethod.Post, "myrequest");
using var content = new MultipartFormDataContent
{
    {new StreamContent(image), "data", "file.ext"},
    {JsonContent.Create(myObject), "Object"}
};
request.Content = content;
using var res = await _httpClient.SendAsync(request);

...

This works, except that the company policy is to serialize Json fields in PascalCase, whereas JsonSerializerDefaults.Web, which is used by JsonContent, defaults to camelCase.

I can fix this specific instance by writing

{JsonContent.Create(myObject, null, new JsonSerializerOptions() { PropertyNamingPolicy = null }), "Object"}

but the problem then becomes that I have to do this anywhere where I build such a request.

My question: can I set PascalCase for JsonContent globally somewhere?

I can set this for the controllers via builder.Services.AddControllers().AddJsonOptions(options => options.JsonSerializerOptions.PropertyNamingPolicy = null);, and there are questions such as How to set default json serialization settings for HttpClient (WinForms) , but none of them seem to apply to JsonContent in Asp.Net Core with System.Text.Json.



Solution 1:[1]

As far as I know, there is no option for telling JsonContent.Create() to use the global JsonSerializerOptions.

BUT you could use the options pattern to retrieve the global JsonSerializerOptions, you've added with AddJsonOptions(...);.

Program.cs:

builder.Services.AddControllers().AddJsonOptions(options =>
{
    options.JsonSerializerOptions.PropertyNamingPolicy = null;
});

Options injected in Controller:

private readonly IOptions<JsonOptions> _JsonOptions;

public YourController(IOptions<JsonOptions> options)
{
    _JsonOptions = options;
}

...

// in your request method:
using var request = new HttpRequestMessage(HttpMethod.Post, "myrequest");
using var content = new MultipartFormDataContent
{
    { new StreamContent(image), "data", "file.ext" },
    { JsonContent.Create(wfc, null, JsonOptions.Value.JsonSerializerOptions), "Object" }
};
request.Content = content;
using var res = await _httpClient.SendAsync(request);

...

To simplify things a bit more, you could use a static helper method, so you don't need to pass the type and you can just pass the options.

PascalCaseHelper.cs:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;

using System.Net.Mime;
using System.Text;
using System.Text.Json;

namespace YourNamespace
{
    public static class PascalCaseHelper
    {
        public static StringContent CreateJson(object data, IOptions<JsonOptions> options)
        {
            return new StringContent(
                JsonSerializer.Serialize(data, options.Value.JsonSerializerOptions), 
                Encoding.UTF8,
                MediaTypeNames.Application.Json);
        }
    }
}


// Usage:
{ PascalCaseHelper.CreateJson(myObject, _JsonOptions), "Object" }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 johnmoarr