Keywords: ASP.NET Core 3.0 | JSON Serialization | IMvcBuilder.AddJsonOptions | Newtonsoft.Json | System.Text.Json
Abstract: This technical article examines the disappearance of the IMvcBuilder.AddJsonOptions method when upgrading from ASP.NET Core 2.0 to 3.0. It analyzes Microsoft's architectural shift in .NET Core 3.0, where Json.NET is no longer included by default, and introduces the new System.Text.Json API. The paper provides a comprehensive solution using the Microsoft.AspNetCore.Mvc.NewtonsoftJson package to reconfigure JSON serialization, with detailed code examples for maintaining custom serialization settings. By comparing old and new configuration approaches, it helps developers understand how to preserve control over JSON serialization in the new version, particularly for common requirements like property naming conventions.
Architectural Changes in JSON Serialization for ASP.NET Core 3.0
With the release of ASP.NET Core 3.0, Microsoft implemented significant architectural changes to JSON processing. In previous versions, developers commonly used the IMvcBuilder.AddJsonOptions extension method to configure JSON serialization settings, such as controlling property naming conventions. Typical 2.x configuration code looked like this:
services.AddMvc()
.AddJsonOptions(opts => opts.SerializerSettings.ContractResolver
= new DefaultContractResolver());
However, when upgrading to version 3.0, developers encounter compilation errors indicating that the AddJsonOptions method is no longer available. This is not merely an API change but reflects a fundamental shift in Microsoft's JSON processing strategy for .NET Core 3.0.
Technical Background of Architectural Changes
One of the most significant changes in ASP.NET Core 3.0 is the removal of default dependency on Json.NET (Newtonsoft.Json). According to official announcements, this decision was primarily driven by two considerations: first, Microsoft aimed to provide a more performant built-in JSON API; second, reducing default framework dependencies to simplify deployment. The new System.Text.Json API focuses on high performance and low memory allocation, but as a trade-off, it does not include all features of Json.NET.
This architectural change directly affected MVC framework configuration. In version 2.x, the AddJsonOptions method was provided by the Microsoft.AspNetCore.Mvc.Formatters.Json package, which encapsulated Json.NET integration. In 3.0, this package is no longer included by default, causing the related extension methods to become unavailable.
Solution: Reintegrating Json.NET
For projects requiring backward compatibility or depending on specific Json.NET features, Microsoft provides a clear migration path. The core solution involves reintroducing Json.NET support through the NuGet package Microsoft.AspNetCore.Mvc.NewtonsoftJson.
The configuration process involves two steps: first, add a reference to Microsoft.AspNetCore.Mvc.NewtonsoftJson via package manager or command-line tools; second, update service configuration in the Startup class's ConfigureServices method. Basic configuration code is as follows:
services.AddControllers()
.AddNewtonsoftJson();
This simple call configures MVC controllers to use Json.NET instead of the new System.Text.Json API. Notably, AddControllers replaces the older AddMvc, representing another improvement in controller registration for version 3.0.
Advanced Configuration and Custom Options
The AddNewtonsoftJson method provides overloaded versions that allow developers to customize JSON serialization settings as before. The following example demonstrates how to configure a contract resolver for specific naming strategies:
services.AddControllers()
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
// Additional Json.NET configuration options
options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
options.SerializerSettings.DateFormatHandling = DateFormatHandling.IsoDateFormat;
});
This configuration approach not only restores the functionality of AddJsonOptions but also maintains the same programming model, making migration of existing code relatively smooth. Developers can continue using the familiar JsonSerializerSettings class to configure all Json.NET features.
Considerations for Architectural Choices
When choosing between the new System.Text.Json API and continuing with Json.NET, developers should consider several key factors. System.Text.Json offers better performance characteristics, particularly in high-throughput scenarios, but its feature set is currently less complete than Json.NET's. Json.NET provides richer functionality, including more flexible serialization control, better third-party library compatibility, and more mature community support.
For new projects that do not require specific Json.NET features, consider using System.Text.Json directly. For existing projects or scenarios requiring advanced JSON processing capabilities, integrating Json.NET via Microsoft.AspNetCore.Mvc.NewtonsoftJson is more appropriate. This flexibility is one of the key advantages of ASP.NET Core 3.0's design.
Best Practices and Migration Recommendations
When performing version migration, a gradual strategy is recommended. First, assess the project's dependency on specific Json.NET features, then decide whether integration of the NewtonsoftJson package is necessary. For most enterprise applications, continuing with Json.NET is often the safer choice due to dependencies on legacy code and third-party libraries.
During configuration, note that the AddNewtonsoftJson method should be called immediately after controller registration to ensure proper application of settings. Additionally, centralizing JSON configuration options is recommended for easier maintenance and testing. For team projects, clearly document the rationale behind JSON serialization strategy choices and configuration details.
The JSON architectural changes in ASP.NET Core 3.0 reflect Microsoft's response to performance requirements and modern web development needs. While this introduces short-term migration costs, the Microsoft.AspNetCore.Mvc.NewtonsoftJson package allows developers to balance the advantages of the new architecture with compatibility requirements of existing code. Understanding the design philosophy behind these changes helps make more informed technical decisions and build more robust applications.