
May 4, 2026 09:06 by
Peter
The process of transforming C# objects into JSON strings (for responses) and back again (for request bodies) is known as JSON serialization in ASP.NET Core Web API. Although ASP.NET Core takes care of this automatically by default, creating professional APIs requires knowing how to customize it.

[HttpGet]
public IActionResult GetUser()
{
var user = new User { Id = 1, Name = "Alice" };
return Ok(user); // Automatically serialized to {"id": 1, "name": "Alice"}
}
2. Configuration & Global Settings
You can customize serialization behavior globally in your Program.cs. Common tasks include enabling "pretty printing" (indentation) or changing how property names are cased.
builder.Services.AddControllers()
.AddJsonOptions(options =>
{
// 1. Indent the JSON for readability
options.JsonSerializerOptions.WriteIndented = true;
// 2. Ignore properties that are null
options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
// 3. Keep property names as they are in C# (PascalCase) instead of camelCase
options.JsonSerializerOptions.PropertyNamingPolicy = null;
});
3. Using Attributes for Fine Control
Sometimes you only want to change serialization for a specific class or property. You can use attributes directly on your models:
| Attribute |
Purpose |
| [JsonPropertyName("user_id")] |
Renames the property in the JSON output. |
| [JsonIgnore] |
Prevents the property from being serialized at all. |
| [JsonInclude] |
Forces a private property to be included. |
| [JsonConstructor] |
Tells the serializer which constructor to use for deserialization. |
Example:
public class Product
{
[JsonPropertyName("sku_code")]
public string Sku { get; set; }
[JsonIgnore]
public decimal InternalCost { get; set; }
}
4. System.Text.Json vs. Newtonsoft. Json
While System.Text.Json is the default, many legacy or complex projects still use Newtonsoft.Json (Json.NET).
| Feature |
System.Text.Json (Default) |
Newtonsoft.Json (Json.NET) |
| Performance |
Faster, uses less memory. |
Slower due to heavy reflection. |
| Compatibility |
Built into .NET. |
Requires a NuGet package. |
| Features |
Strict, standard-compliant. |
Highly flexible, handles edge cases easily. |
| Native AOT |
Fully supported (via Source Gen). |
Not supported. |
How to switch to Newtonsoft.Json:
If you need specific features like JsonPatch or complex reference handling, install the Microsoft.AspNetCore.Mvc.NewtonsoftJson package and update Program.cs:
builder.Services.AddControllers().AddNewtonsoftJson();
5. Best Practices for 2026
Stick to System.Text.Json: Unless you have a specific technical debt reason to use Newtonsoft, the performance gains and security of the built-in library are worth it.
Use Source Generation: For high-traffic APIs or Cloud Native/Native AOT apps, use JSON Source Generators to eliminate reflection at runtime.
Avoid Circular References: If your models reference each other (e.g., Parent → Child → Parent), use ReferenceHandler.IgnoreCycles to prevent the serializer from crashing.
Contracts First: Always define DTOs (Data Transfer Objects) specifically for your API rather than serializing your Database Entities directly.
Are you looking to migrate an existing project from Newtonsoft.Json, or are you starting a fresh project from scratch?