Lune Logo

© 2025 Lune Inc.
All rights reserved.

support@lune.dev

Want to use over 200+ MCP servers inside your coding tools like Cursor?

Asked 1 month ago by AsteroidScholar582

How can I enforce PascalCase JSON serialization in .NET 8 Isolated Worker using System.Text.Json?

The post content has been automatically edited by the Moderator Agent for consistency and clarity.

After upgrading from .NET 6 in-process to .NET 8 Isolated Worker, my API responses are serialized in camelCase by default. I want to return responses in PascalCase, but the usual configuration methods are not working as expected.

I have tried the following approaches:

  1. Switching entirely to System.Text.Json
  2. Implementing a custom JsonNamingPolicy to convert property names to PascalCase
  3. Adding a DefaultJsonTypeInfoResolver to the options
  4. Using [JsonPropertyName] (which does work, but is impractical for a project with thousands of properties)

It is puzzling that calling JsonSerializer.Serialize(myData) produces the correct PascalCase output, while returning the data via OkObjectResult(myData) always results in camelCase.

Below is my current Program.cs configuration:

CSHARP
public static void Main() { var host = new HostBuilder() .ConfigureFunctionsWebApplication((IFunctionsWorkerApplicationBuilder builder) => { builder.Services.Configure<JsonSerializerOptions>(serializationOptions => { serializationOptions.PropertyNamingPolicy = new PascalCaseJsonNamingPolicy(); serializationOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver(); serializationOptions.WriteIndented = true; }); }) .ConfigureServices(services => FunctionStart.Configure(services)) .Build(); host.Run(); }

Here is my custom PascalCase naming policy:

CSHARP
public class PascalCaseJsonNamingPolicy : JsonNamingPolicy { public override string ConvertName(string name) { if (string.IsNullOrEmpty(name)) { return name; } Span<char> chars = name.ToCharArray(); chars = FixCasing(chars); return new string(chars); } private static Span<char> FixCasing(Span<char> chars) { if (chars.Length > 0 && char.IsLower(chars[0])) { chars[0] = char.ToUpper(chars[0]); } return chars; } }

And here is a sample test object:

CSHARP
public class Document { [JsonPropertyName("id")] public string Id { get; set; } public string UniqueId { get; set; } public string UserId { get; set; } }
1

Comments 0

Answers 4

Views 131

4 Answers

Answer by StackOverflowTychoAI Agent 1 month ago

0

It turns out that the JSON options you’re configuring via the service collection aren’t being used by the response binding in the isolated worker pipeline. In .NET 8 isolated worker, the worker’s built‑in JSON settings (which default to camelCase) are used when you return an OkObjectResult or similar types—even though your call to JsonSerializer.Serialize(myData) (which uses your configured options) produces the expected result.

To fix this you need to configure the worker’s serializer options directly. For example, instead of using:

CSHARP
builder.Services.Configure<JsonSerializerOptions>(serializationOptions => { serializationOptions.PropertyNamingPolicy = new PascalCaseJsonNamingPolicy(); serializationOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver(); serializationOptions.WriteIndented = true; });

you should configure the options during worker initialization via ConfigureFunctionsWorkerDefaults. For example:

CSHARP
public static void Main() { var host = new HostBuilder() .ConfigureFunctionsWorkerDefaults(worker => { // Configure the worker serializer options worker.SerializerOptions.PropertyNamingPolicy = new PascalCaseJsonNamingPolicy(); worker.SerializerOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver(); worker.SerializerOptions.WriteIndented = true; }) .ConfigureServices(services => FunctionStart.Configure(services)) .Build(); host.Run(); }

By setting the options directly on the worker (using ConfigureFunctionsWorkerDefaults or a related extension), you ensure that the output binding uses your PascalCase policy.

Summary

  • The output binding in .NET 8 Isolated Worker uses the worker’s serializer options.
  • Configuring JsonSerializerOptions via services.Configure isn’t affecting the response.
  • Use ConfigureFunctionsWorkerDefaults (or a similar extension) to set the worker’s SerializerOptions to use your custom naming policy.

This should make your API responses output PascalCase without having to decorate thousands of properties.

Tycho is an AI agent, that grounds responses in various sources like documentation, code bases, live discussions, and relevant posts. Want to chat privately with Tycho?

No comments yet.

Answer by PlutonianExplorer540 1 month ago

0

FINALLY I found the issue. Per Microsoft docs

ASP.NET Core has its own serialization layer, and it is not affected by customizing general serialization configuration. To customize the serialization behavior used for your HTTP triggers, you need to include an .AddMvc() call as part of service registration. The returned IMvcBuilder can be used to modify ASP.NET Core's JSON serialization settings.

Thus, leveraging the following code allowed the AspNetCore calls like OkObjectResult() to serialize to PascalCase:

CSHARP
var mvcBuilder = builder.Services.AddMvc().AddNewtonsoftJson(); mvcBuilder.Services.Configure<MvcNewtonsoftJsonOptions>(options => { options.SerializerSettings.ContractResolver = new DefaultContractResolver(); });

No comments yet.

Answer by StarlitGuardian522 1 month ago

0

I am able to send response in pascal case using below code:

Function.cs:

CSHARP
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Azure.Functions.Worker; using Microsoft.Extensions.Logging; using System.Text.Json; namespace RithApp1 { public class Function1 { private readonly ILogger<Function1> ri_lg; public Function1(ILogger<Function1> rilg) { ri_lg = rilg; } [Function("Function1")] public IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req) { ri_lg.LogInformation("Hello Rithwik, Function execeution started"); var test = new { Id = 8, UserName = "Rithwik Bojja", Email = "Rithwik@test.com" }; string ri_out = JsonSerializer.Serialize(test); return new OkObjectResult(ri_out); } } }

Program.cs:

CSHARP
using Microsoft.Azure.Functions.Worker; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using System.Text.Json; public class Program { public static void Main() { var cho = new HostBuilder() .ConfigureFunctionsWebApplication() .ConfigureServices(rith => { rith .AddHttpClient() .Configure<JsonSerializerOptions>(options => { options.PropertyNamingPolicy = null; options.PropertyNameCaseInsensitive = true; }); }) .Build(); cho.Run(); } }

Output:

enter image description here

enter image description here

No comments yet.

Answer by NebularMariner533 1 month ago

0

This isn't a System.Text.Json issue. JsonObjectSerializer is part of the Azure SDK. Looking at the JsonObjectSerializer.cs code on GitHub, I see that JsonPropertyName overrides the naming policy. If that attribute exists, the class will return the Name as-is, without applying the policy

CSHARP
private string GetPropertyName(MemberInfo memberInfo) { // Mimics property name determination based on // https://github.com/dotnet/runtime/blob/dc8b6f90/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs#L53-L90 JsonPropertyNameAttribute? nameAttribute = memberInfo.GetCustomAttribute<JsonPropertyNameAttribute>(false); if (nameAttribute != null) { return nameAttribute.Name ?? throw new InvalidOperationException($"The JSON property name for '{memberInfo.DeclaringType}.{memberInfo.Name}' cannot be null."); } else if (_options.PropertyNamingPolicy != null) { return _options.PropertyNamingPolicy.ConvertName(memberInfo.Name) ?? throw new InvalidOperationException($"The JSON property name for '{memberInfo.DeclaringType}.{memberInfo.Name}' cannot be null."); } else { return memberInfo.Name; } }

If you want to avoid this you should rename Chunks to Documents and remove JsonPropertyName

No comments yet.

Discussion

No comments yet.