Introduction
Learn how to properly use a JsonConverter, along with property and global setup for converters.
Before getting started, the converter is intentionally simple. The focus here is proper planning for the data for a specific task, like importing data from a JSON file into a database, in this case, properly formatted.
Sample converter
Reads and converts the JSON string value to ensure the first character to uppercase.
public class UpperCaseFirstCharConverter : JsonConverter<string>
{
public override bool CanConvert(Type typeToConvert)
=> typeToConvert == typeof(string);
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> (reader.GetString() ?? string.Empty).CapitalizeFirstLetter();
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
{
writer.WriteStringValue(value ?? "Null");
}
}
Example usage
Proper-case FirstName and LastName from a JSON file.
Sample data
[
{
"Id": 1,
"FirstName": "jose",
"LastName": "fernandez",
"BirthDate": "1985-01-01"
},
{
"Id": 2,
"FirstName": "Miguel",
"LastName": "loPez",
"BirthDate": "1970-12-04"
},
{
"Id": 3,
"FirstName": "angel",
"LastName": "PEREZ",
"BirthDate": "1980-09-11"
}
]
Modal/class
public class Person
{
public int Id { get; set; }
public required string FirstName { get; set; }
public required string LastName { get; set; }
public DateOnly BirthDate { get; set; }
}
Code
public static void GlobalExample()
{
SpectreConsoleHelpers.PrintPink();
string json =
/*lang=json*/
"""
[
{
"Id": 1,
"FirstName": "jose",
"LastName": "fernandez",
"BirthDate": "1985-01-01"
},
{
"Id": 2,
"FirstName": "Miguel",
"LastName": "loPez",
"BirthDate": "1970-12-04"
},
{
"Id": 3,
"FirstName": "angel",
"LastName": "PEREZ",
"BirthDate": "1980-09-11"
}
]
""";
AnsiConsole.MarkupLine("[bold yellow]Original JSON:[/]");
SpectreConsoleHelpers.PresentJson(json);
Console.WriteLine("\n");
AnsiConsole.MarkupLine("[bold blue]Deserialized and Serialized JSON (with capitalized names):[/]");
var people = JsonSerializer.Deserialize<List<Person>>(json, GlobalJsonOptions);
var json1 = JsonSerializer.Serialize(people, GlobalJsonOptions);
SpectreConsoleHelpers.PresentJson(json1);
}
private static readonly JsonSerializerOptions GlobalJsonOptions = new()
{
Converters = { new UpperCaseFirstCharConverter() },
WriteIndented = true
};
For ASP.NET Core in Program.cs
/*
* Register the custom JSON converter globally for all Razor Pages.
* This ensures that the converter is applied to all JSON serialization
* and deserialization operations.
*/
builder.Services
.AddRazorPages()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.Converters.Add(
new UpperCaseFirstCharConverter());
});
Results from a console project
Suppose the following data was used, the State property will be changed.
[
{
"Id": 1,
"FirstName": "jose",
"LastName": "fernandez",
"State": "CA",
"BirthDate": "1985-01-01"
},
{
"Id": 2,
"FirstName": "Miguel",
"LastName": "loPez",
"State": "NY",
"BirthDate": "1970-12-04"
},
{
"Id": 3,
"FirstName": "angel",
"LastName": "PEREZ",
"State": "TX",
"BirthDate": "1980-09-11"
}
]
The fix is to annotate only the FirstName and LastName properties with [JsonConverter] attribute, followed by using the code below, which does not add the converter in the options.
public class Customer
{
public int Id { get; set; }
[JsonConverter(typeof(UpperCaseFirstCharConverter))]
public required string FirstName { get; set; }
[JsonConverter(typeof(UpperCaseFirstCharConverter))]
public required string LastName { get; set; }
public required string State { get; set; }
public DateOnly BirthDate { get; set; }
}
Code
public static void PropertiesExample()
{
SpectreConsoleHelpers.PrintPink();
string json =
/*lang=json*/
"""
[
{
"Id": 1,
"FirstName": "jose",
"LastName": "fernandez",
"State": "CA",
"BirthDate": "1985-01-01"
},
{
"Id": 2,
"FirstName": "Miguel",
"LastName": "loPez",
"State": "NY",
"BirthDate": "1970-12-04"
},
{
"Id": 3,
"FirstName": "angel",
"LastName": "PEREZ",
"State": "TX",
"BirthDate": "1980-09-11"
}
]
""";
AnsiConsole.MarkupLine("[bold yellow]Original JSON:[/]");
SpectreConsoleHelpers.PresentJson(json);
Console.WriteLine("\n");
AnsiConsole.MarkupLine("[bold blue]Deserialized and Serialized JSON (with capitalized names):[/]");
var people = JsonSerializer.Deserialize<List<Customer>>(json, Options);
var json1 = JsonSerializer.Serialize(people, Options);
SpectreConsoleHelpers.PresentJson(json1);
}
private static JsonSerializerOptions Options => new() { WriteIndented = true };
Results
Console Source code ASP.NET Core Source code
Summary
The takeaway is that a developer plans properly before starting a task like the converter used here.


Top comments (0)