Deserialize JSON using different property names in C#
By Tan Lee Published on Feb 05, 2025 584
- Use the
JsonPropertyName
attribute. - Use a built-in or custom naming policy.
- A combination of both: Use
JsonPropertyName
for special cases that your naming policy doesn’t address.
These solutions work for both deserialization and serialization.
For example, consider the following JSON with snake-cased property names:
{ "user_id": 1, "first_name": "John", "last_name": "Doe", "date_joined": "2010-05-15T00:00:00" }
Using the JsonPropertyName Attribute:
If you have control over the class, you can use the JsonPropertyName
attribute to map the JSON property names to the C# property names:
using System.Text.Json.Serialization; public class User { [JsonPropertyName("user_id")] public int UserId { get; set; } [JsonPropertyName("first_name")] public string FirstName { get; set; } [JsonPropertyName("last_name")] public string LastName { get; set; } [JsonPropertyName("date_joined")] public DateTime DateJoined { get; set; } }
Using a Naming Policy:
If you want a uniform approach where all property names are affected, you can use a JsonNamingPolicy
. Here’s an example using the built-in CamelCase
naming policy:
using System.Text.Json; var options = new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; var user = JsonSerializer.Deserialize<User>(userJson, options);
While CamelCase
is the default built-in policy, you can also create custom naming policies for other formats, like snake case.
Creating a Custom Naming Policy:
You can create a custom naming policy by subclassing JsonNamingPolicy
and overriding the ConvertName
method. Here’s an example of implementing a simple snake case naming policy:
using System.Text.Json; public class SnakeCaseNamingPolicy : JsonNamingPolicy { public override string ConvertName(string name) { var sb = new StringBuilder(); bool lastWasLower = false; foreach (var c in name) { if (lastWasLower && char.IsUpper(c)) sb.Append('_'); lastWasLower = char.IsLower(c); sb.Append(char.ToLower(c)); } return sb.ToString(); } }
To use the custom policy, assign it to the JsonSerializerOptions
:
var options = new JsonSerializerOptions() { PropertyNamingPolicy = new SnakeCaseNamingPolicy() }; var user = JsonSerializer.Deserialize<User>(userJson, options);
Name Mappings with a Dictionary
If your JSON uses names that don't follow any recognizable pattern, you can use a dictionary to map class property names to JSON names.
using System.Text.Json; public class CustomNamingPolicy : JsonNamingPolicy { private readonly Dictionary<string, string> NameMapping = new Dictionary<string, string>() { [nameof(User.UserId)] = "user_id", [nameof(User.FirstName)] = "first_name", [nameof(User.LastName)] = "last_name", [nameof(User.DateJoined)] = "date_joined" }; public override string ConvertName(string name) { return NameMapping.GetValueOrDefault(name, name); } }
Third-Party Library for Snake Case
System.Text.Json doesn't natively support snake case or other strategies like kebab case.
To address this, you can use third-party libraries such as JorgeSerrano.Json.JsonSnakeCaseNamingPolicy
.
First, you need to install the package via NuGet:
Install-Package JorgeSerrano.Json.JsonSnakeCaseNamingPolicy
Then configure it in your JsonSerializerOptions
:
using System.Text.Json; using JorgeSerrano.Json; var options = new JsonSerializerOptions() { PropertyNamingPolicy = new JsonSnakeCaseNamingPolicy() }; var user = JsonSerializer.Deserialize<User>(userJson, options);
By using JsonPropertyName
, custom naming policies, or third-party libraries, you can easily handle cases where JSON and class property names don't align.
- Serialize and Deserialize a Multidimensional Array in JSON using C#
- JSON object contains a trailing comma at the end which is not supported
- How to use JsonDocument to read JSON in C#
- How to use JsonExtensionData in C#
- Serialize a tuple to JSON in C#
- Deserialize JSON to a derived type in C#
- Deserialize JSON to a dictionary in C#
- Deserialize a JSON array to a list in C#