Json.Net
StringEnumConverter
enums
global setting
serialization

How to tell Json.Net globally to apply the StringEnumConverter to all enums

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

When an API sends enums as integers, clients become tightly coupled to the server’s internal numeric values. A renamed member or inserted enum item can silently break consumers that assumed a fixed numeric mapping. In most public APIs, enum strings are safer because they are explicit, readable, and easier to debug in logs. Json.NET solves this with StringEnumConverter, but many teams only apply it on individual properties and end up with inconsistent payloads. The reliable approach is to configure conversion globally so every enum is serialized and deserialized using the same rule.

Global configuration also reduces repetition. You do not need [JsonConverter] attributes on every model, and new enums automatically follow the project standard. This article shows how to set that up, how to harden deserialization behavior, and how to avoid common mistakes that produce confusing runtime bugs.

Core Sections

Configure a global converter in plain Json.NET

If you serialize with JsonConvert.SerializeObject, attach the converter once through JsonSerializerSettings and reuse that settings object.

csharp
1using Newtonsoft.Json;
2using Newtonsoft.Json.Converters;
3using Newtonsoft.Json.Serialization;
4
5public enum OrderState { PendingApproval, InProgress, Completed }
6
7var settings = new JsonSerializerSettings
8{
9    Converters = { new StringEnumConverter(new CamelCaseNamingStrategy()) }
10};
11
12var payload = JsonConvert.SerializeObject(new { State = OrderState.InProgress }, settings);
13// {"state":"inProgress"} when combined with camel-case property naming

This ensures every enum in the object graph uses string values. If your API contract expects exact enum names, instantiate StringEnumConverter() without a naming strategy.

Configure globally in ASP.NET Core (Newtonsoft.Json)

If your application is ASP.NET Core and uses AddNewtonsoftJson, register the converter in startup so controllers inherit it automatically.

csharp
1builder.Services
2    .AddControllers()
3    .AddNewtonsoftJson(options =>
4    {
5        options.SerializerSettings.Converters.Add(
6            new StringEnumConverter(new CamelCaseNamingStrategy())
7        );
8
9        options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
10    });

Now any request/response model enum goes through the same converter. This keeps contract behavior consistent across endpoints and avoids per-controller drift.

Handle unknown enum values intentionally

By default, deserialization throws if an enum string cannot map to a member. For external clients, that can produce noisy failures. You can introduce a defensive fallback by adding an Unknown member and validating input.

csharp
1public enum PaymentStatus
2{
3    Unknown = 0,
4    Authorized,
5    Captured,
6    Refunded
7}
8
9public static PaymentStatus ParseStatus(string raw)
10{
11    return Enum.TryParse<PaymentStatus>(raw, ignoreCase: true, out var parsed)
12        ? parsed
13        : PaymentStatus.Unknown;
14}

This pattern is especially useful for queue consumers, import jobs, or backward-compatible APIs where you prefer graceful degradation over hard failure.

Use flags enums carefully

[Flags] enums serialize as comma-separated names (for example, "Read, Write") when values combine. That may be hard for non-.NET clients. If interoperability matters, document the format explicitly or avoid flags in external contracts.

csharp
1[Flags]
2public enum Permission
3{
4    None = 0,
5    Read = 1,
6    Write = 2,
7    Delete = 4
8}
9
10var p = Permission.Read | Permission.Write;
11var json = JsonConvert.SerializeObject(new { Permission = p }, settings);

For internal services, this is fine. For public APIs, consider sending a string array (["read","write"]) through a dedicated DTO so consumers parse predictably.

Prefer one policy for naming

If enum strings are camelCase but enum declarations are PascalCase, team members may assume a bug when reading payloads. Pick one naming strategy and enforce it in tests.

csharp
1[Fact]
2public void Enum_is_serialized_consistently()
3{
4    var settings = new JsonSerializerSettings
5    {
6        Converters = { new StringEnumConverter(new CamelCaseNamingStrategy()) }
7    };
8
9    var json = JsonConvert.SerializeObject(new { State = OrderState.PendingApproval }, settings);
10    Assert.Contains("pendingApproval", json);
11}

Contract tests like this catch accidental configuration changes during framework upgrades or refactors.

Common Pitfalls

  • Registering StringEnumConverter in one serialization path but not another, causing the same model to emit both integers and strings.
  • Mixing System.Text.Json defaults with Json.NET settings in the same app and assuming converters apply to both serializers.
  • Applying a naming strategy globally without checking client expectations, which can break strict string matching in existing integrations.
  • Forgetting to document [Flags] enum output format, leading external consumers to mis-parse combined values.
  • Treating unknown enum values as impossible and letting imports fail instead of providing an explicit fallback policy.

Summary

Global enum string handling in Json.NET is mostly about consistency. Configure StringEnumConverter once at the serializer level, decide your naming policy, and test contract output so behavior stays stable over time. If your application receives data from outside your control, add a strategy for unknown values instead of relying on exceptions alone. For public APIs, be careful with flags enums and document wire formats clearly. With these practices, enum serialization becomes predictable, readable, and safer for long-lived integrations.


Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.