195

I've just upgraded my ASP web API project from .Net core 2.0 to 3.0. I was using

     services.AddMvc()
             .AddJsonOptions(options =>options.SerializerSettings.ContractResolver 
                                       = new DefaultContractResolver());

previously to ensure lower-casing of the serialized JSON.

After the upgrade to 3.0 I get this error:

Error CS1061 'IMvcBuilder' does not contain a definition for 'AddJsonOptions' and no accessible extension method 'AddJsonOptions' accepting a first argument of type 'IMvcBuilder' could be found (are you missing a using directive or an assembly reference?)

According to AddJsonOptions for MvcJsonOptions in Asp.Net Core 2.2 the AddJsonOptions extension method is/was provided by the Microsoft.AspNetCore.Mvc.Formatters.Json nuget package. I have tried installing/reinstalling this but still can't resolve the method. Interestingly, intellisense only shows Microsoft.AspNetCore.Mvc.Formatters.Xml when I try to add the using statement even though I added the Json nuget package.

Any ideas what is going on? The documentation for AddJsonOptions only goes up to .Net 2.2 so perhaps the method has been deprecated in 3.0 in favor of some other configuration mechanism?

ArunPratap
  • 4,816
  • 7
  • 25
  • 43
NeilMacMullen
  • 3,339
  • 2
  • 20
  • 22

7 Answers7

330

As part of ASP.NET Core 3.0, the team moved away from including Json.NET by default. You can read more about that in general in the announcement on breaking changes to Microsoft.AspNetCore.App.

Instead of Json.NET, ASP.NET Core 3.0 and .NET Core 3.0 include a different JSON API that focuses a bit more on performance. You can learn about that more in the announcement about “The future of JSON in .NET Core 3.0”.

The new templates for ASP.NET Core will no longer bundle with Json.NET but you can easily reconfigure the project to use it instead of the new JSON library. This is important for both compatibility with older projects and also because the new library is not supposed to be a full replacement, so you won't see the full feature set there.

In order to reconfigure your ASP.NET Core 3.0 project with Json.NET, you will need to add a NuGet reference to Microsoft.AspNetCore.Mvc.NewtonsoftJson, which is the package that includes all the necessary bits. Then, in the Startup’s ConfigureServices, you will need to configure MVC like this:

services.AddControllers()
    .AddNewtonsoftJson();

This sets up MVC controllers and configures it to use Json.NET instead of that new API. Instead of controllers, you can also use a different MVC overload (e.g. for controllers with views, or Razor pages). That AddNewtonsoftJson method has an overload that allows you to configure the Json.NET options like you were used to with AddJsonOptions in ASP.NET Core 2.x.

services.AddControllers()
    .AddNewtonsoftJson(options =>
    {
        options.SerializerSettings.ContractResolver = new DefaultContractResolver();
    });
poke
  • 369,085
  • 72
  • 557
  • 602
  • 69
    For those following along at home... when migrating a project you may need to add a nuget reference to "Microsoft.AspNetCore.Mvc.NewtonsoftJson" to get the "AddNewtonsoftJson" extension. At the time of writing this requires "include prereleases" to be checked if you are using the Visual Studio Nuget manager. – NeilMacMullen Apr 13 '19 at 15:23
  • 1
    Note that I would generally not recommend migrating to ASP.NET Core 3 with real applications just yet. If you just want to play around, sure, but there are still a few moving bits before the final release, so you will have to keep that in mind if you want to migrate to it early. – poke Apr 13 '19 at 15:38
  • 1
    This can trigger "Synchronous operations are disallowed" check https://stackoverflow.com/questions/47735133/asp-net-core-synchronous-operations-are-disallowed-call-writeasync-or-set-all for more info – verbedr Aug 14 '19 at 14:02
  • @verbedr It should work in the current previews of ASP.NET Core 3.0 though. The bug was fixed for preview 4. – poke Aug 14 '19 at 14:19
  • @poke it is solved with small payloads if you get a larger response the error is still there. This is the exception I just got with the latest (preview 8) library. System.InvalidOperationException: Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead. ...... at Newtonsoft.Json.Utilities.JavaScriptUtils.WriteEscapedJavaScriptString(TextWriter writer, String s, Char delimiter, Boolean appendDelimiters, Boolean[] charEscapeFlags, StringEscapeHandling stringEscapeHandling, IArrayPool`1 bufferPool, Char[]& writeBuffer) – verbedr Aug 15 '19 at 13:16
  • @poke FYI so the solution was to buffer the response fully when using Newtonsoft and some other scenarios (https://github.com/aspnet/AspNetCore/issues/6397) but if it goes above some threshold it will still trigger this error. davidfowl was talking about making it configurable ... – verbedr Aug 15 '19 at 13:28
  • hard to follow. – Vy Do Sep 29 '19 at 09:27
  • 1
    and what if i *DO* want to use the new one! – Simon_Weaver Oct 15 '19 at 18:08
  • @Simon_Weaver The new JSON serializer is enabled by default so you don’t need to do anything to use it. It does not support as much customization as Json.NET though (that’s one of the big differences) but you can check out the [serializer options](https://learn.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializeroptions?view=netcore-3.0) to see what you can change. You can call `AddJsonOptions(…)` on the MVC builder to configure the serializer. – poke Oct 15 '19 at 22:54
  • Thanks. I only just installed 3.0 today so the goal was to just get it working. I do however have a custom date format I was using but so it was easiest to just revert to Json.NET for now. It was super easy before to set just a date format. – Simon_Weaver Oct 15 '19 at 23:02
  • 21
    For me `AddNewtonsoftJson` is missing, even after referencing that `Microsoft.AspNetCore.Mvc.NewtonsoftJson` reference. – Saeed Neamati Oct 22 '19 at 10:15
  • @SaeedNeamati Make sure you have a `using Microsoft.Extensions.DependencyInjection` to see the `AddNewtonsoftJson` extension method. – poke Nov 02 '19 at 17:09
  • I found out, after porting to 3.0, that the new JsonSerializer doesn't respect the `[IgnoreDataMember]` attribute. – avenmore Nov 17 '19 at 14:25
  • 2
    @avenmore The new serializer uses a separate set of attributes. You can use `[JsonIgnore]` from the `System.Text.Json.Serialization` namespace. – poke Nov 17 '19 at 14:59
  • @poke Yes, thank you, it was just a gotcha where behaviour changed silently and errors appeared on the client. It was mentioned in [this Github issue](https://github.com/dotnet/corefx/issues/40062) that anything coming from the `System.Runtime.Serialization` namespace will never be supported. – avenmore Nov 18 '19 at 15:29
  • 1
    I've used only AddJsonFormatters() extension method: services.AddMvcCore().AddJsonFormatters() - will it be enough to use services.AddMvcCore().AddNewtonsoftJson() for replacement? – Sergey Nikitin Nov 27 '19 at 16:33
  • 1
    FYI, `AddNewtonsoftJson` has to be chained after `AddControllers`. `services.AddNewtonsoftJson()` does not work. – Rudey Jan 30 '20 at 14:02
  • Adding Microsoft.AspNetCore.Mvc.NewtonsoftJson, I got an error: NU1202: Package Microsoft.AspNetCore.Mvc.NewtonsoftJson 5.0.0 is not compatible with netcoreapp3.0. – Louis Nov 19 '20 at 04:08
  • 5
    @Louis If you are using ASP.NET Core 3.1, you will need to add version `3.1.x` of that package. If you are using ASP.NET Core 3.0 (which isn’t supported any more), you will need to add version `3.0.x` of that package. – poke Nov 19 '20 at 09:39
  • Creating a dotnet 5 aspnet app for the first time, after years working with .net framework onward, found that controller simply did not return objects, just strings. This solution resolved the issue. I don't follow every nuanced change and the serialization option syntax seems to change every year (I prefer pascal case) but this was, have to admit, a bit scary. All's well that ends well, thank you. – Rodney Oct 25 '21 at 15:19
34

This worked for me, while using .Net Core 3:

services.AddMvc().AddJsonOptions(o =>
{
    o.JsonSerializerOptions.PropertyNamingPolicy = null;
    o.JsonSerializerOptions.DictionaryKeyPolicy = null;
});
Nicke Manarin
  • 3,026
  • 4
  • 37
  • 79
Mohammad Olfatmiri
  • 1,605
  • 5
  • 31
  • 57
  • 1
    I would assume the line should be: `o.JsonSerializerOptions.PropertyNameCaseInsensitive = false;` – Grandizer Oct 31 '19 at 12:14
  • 1
    Yeah me too, but it does not. This answer worked for me though. – Martin Nov 05 '19 at 15:36
  • 2
    No need for `o.JsonSerializerOptions.DictionaryKeyPolicy = null;` and `o.JsonSerializerOptions.PropertyNameCaseInsensitive = false;` – Shahar Shokrani Nov 24 '19 at 09:51
  • 1
    I wish I could use this answer, but my application was built using Newtonsoft attributes, which the new MS serializer ignores, meaning that I have to continue using the Newtonsoft serializer with AddNewtonsoftJson. Maybe MS could add an option to respect Newtonsoft attributes, while still getting the performance gains they are promising. – Eric Feb 19 '20 at 16:03
  • @eric Yes you are right but, Newtonsoft performance is enough for most of the situations. – Mohammad Olfatmiri Feb 20 '20 at 17:25
20

Make sure that you installed the Microsoft.AspNetCore.Mvc.NewtonsoftJson package.

enter image description here

Drilon Ahmetaj
  • 525
  • 5
  • 7
6

It's work for me, Install the NewtonsoftJson package from NuGet "dotnet add package Microsoft.AspNetCore.Mvc.NewtonsoftJson --version 3.1.0" version 3.1.0 working for ASP.NET Core 3.0 and use the Following Code-

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
    .AddNewtonsoftJson(opt => {
        opt.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
    });

Hope it's Working Fine, Thanks.

SAM
  • 89
  • 1
  • 6
5

This would help try Installing the Nuget Package

Microsoft.AspNetCore.Mvc.NewtonsoftJson

Adil Bhatti
  • 59
  • 1
  • 2
4

This would help

public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers().AddJsonOptions(options=> {  options.JsonSerializerOptions.PropertyNamingPolicy = null;
                 options.JsonSerializerOptions.DictionaryKeyPolicy = null;

            });

            services.AddDbContext<PaymentDetailContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DevConnection")));
        }
Joey
  • 1,436
  • 2
  • 19
  • 33
Nirmala
  • 59
  • 1
-1

This worked for me, while using .Net Core 3: click here

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Mar 17 '22 at 08:02
  • This does not really answer the question. If you have a different question, you can ask it by clicking [Ask Question](https://stackoverflow.com/questions/ask). To get notified when this question gets new answers, you can [follow this question](https://meta.stackexchange.com/q/345661). Once you have enough [reputation](https://stackoverflow.com/help/whats-reputation), you can also [add a bounty](https://stackoverflow.com/help/privileges/set-bounties) to draw more attention to this question. - [From Review](/review/late-answers/31309356) – MD. RAKIB HASAN Mar 21 '22 at 07:14