I just upgraded my medium size application from ASP.NET Core 2.2 to 3.1 and everything seemed to work fine. The upgrade wasn't a very big task but there were some gotchas along the way. One of the gotchas that went unnoticed until I was trying to get a new feature working was particularly hard to debug.
Starting with ASP.NET Core 3.0 the model-binder handling incoming JSON-data uses
System.Text.Json
instead of Json.NET. This shouldn't immediately be any issue, but I am lazy and pragmatic, so when I for reasons want to post my forms using ajax, I iterate over all input-fields and generate a JSON-structure that I POST to my endpoint. HTML being what it is, all integer inputs return their values as strings, and this is what blows up.
Previously the Json.NET parser said "Oh hi, I need an int here, but the incoming value is a string... Hmm.. Is it parsable though? Yes it is! OK, I'll stuff the parsed value into the int property then!". But now, the System.Text.Json
parser doesn't do that. It says "Oh no! I need an int here! But the incoming value is a string! OMG! ABANDON SHIP! AAAAAAaaaaaaaa!!!" and throws away the whole model, giving you a big fat NULL in your incoming parameter. And failing silently of course. To find out what's going on you need to inspect the ModelState
, and sure enough, the ModelState
reports an error parsing a Int32 from the provided value "0".
The fix, not including actually posting the correct model to begin with (lazy, remember) is adding the package Microsoft.AspNetCore.Mvc.NewtonsoftJson
and updating your configuration in Startup.cs
to include .AddNewtonsoftJson()
after .AddMvc()
or .AddControllers()
or whatever method you use to add your api-functionality. This will replace the new System.Text.Json parser with the old true and tried Newtonsoft Json.NET parser.
If you want to read more about the new System.Text.Json
namespace you can go here. If you want to read the blog post that I found after screwing around with this for half a work day, it's here
Top comments (2)
We recently upgraded from 2.2 to 3.1 too, and experienced a huge slowdown in json parson when using Microsoft.AspNetCore.Mvc.NewtonsoftJson compared to the old NewtonsoftJson in 2.2 and the new System.Text.Json.
One could nearly think that Microsoft has made the "bridge" between Newtonsoft and net core 3.1 slow on purpose.
Only when running the with new System.Text.Json performance is on par with what we had on .netcore 2.2.
Ran into the same wall 2 months ago and wasted few hours. Newtonsoft is super tolerant, but in reality "0" is not an int and I would prefer that to be error, but in production system with milions of calls a month, that could potentially be a breaking change, so... Newtonsoft it is for now :(