简体   繁体   中英

Why different behavior between ASP.NET Web API 2 & ASP.NET Core 3.1 Web API?

I am posting below data to 2 different api endpoints, one we have in an ASP.NET Web API 2 application and while other I have in an ASP.NET Core 3.1 Web API application.

var data = new Data
            {
                Key = "k1",
                Value = 80
            };

IClient httpClient = new FluentClient("http://localhost:46551/");
var x = httpClient.PostAsync("weatherforecast", data).GetAwaiter().GetResult();

For both Web API applications, my model class is below where Value is object type and this is my hard requirement, I can't go with actual type.

public class Data
{
    public string Key { get; set; }
    public object Value { get; set; }
}

When I am posting data to ASP.NET Web API 2 (with.Net 4.6.1), the VS debugger shows only value correctly without any other payload:

在此处输入图像描述

But for ASP.NET Core 3.1 Web API, the VS debugger shows like this, totally different representation along with ValueKind :

在此处输入图像描述

I have a requirement to write data into Json format with below expected output,

{ "Key":"k1", "Value":80 }

While I am trying to serialize data for the ASP.NET Core 3.1 Web API, I get this output:

var ser = JsonConvert.SerializeObject(data);

{ "Key":"k1", "Value": {"ValueKind":4} }

For the ASP.NET Web API 2 application, though I am getting expected output.

Question, how to get this output { "Key":"k1", "Value":80 } from the ASP.NET Core 3.1 application and why there is a different behavior from both applications?

Thanks,

Were you using Newtonsoft previously? The JSON formatter now included with netcore 3x is default unless you explicitly include another parser such as NewtonSoft. The behavior of the new/default parser has a number of differences from Newtonsoft but the one that has caused my teams the most grief when migrating is that the System.Text.Json parser does NOT make assumptions when identifying JSON. This was most commonly where sometimes a field may be a sometime take a complex JSON object and also contain primitive types in cases such as a boolean or integer. A concrete example for me was a settings concept where it was basically a key/value pair, where key was name of the setting such as GridSettings which was a blob and stored in Postgres as JSON, however another setting such as showHidden was a simple true or false. Newtonsoft would still coerce that boolean into JSON since the backing model and entity model declared it as such where as System.Text.Json says nope, that's just a boolean unless you tell me otherwise.

Try injecting Newtonsoft as your parser in your IoC/Startup and see if that changes the behavior.

some details around differences in new parser: https://docs.microsoft.com/en-us/dotnet/core/compatibility/aspnetcore#authentication-newtonsoftjson-types-replaced

We also had to make adjustments to our formatters in certain scenarios:

custom formatter: https://code-maze.com/content-negotiation-dotnet-core/

All in all I do think the parser which makes no assumptions means well and probably is a good thing. However in my case we simply were not ready to make all the corrections needed to counteract this change. Thus for now, we're sticking with good old Newtonsoft.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM