为什么 ASP.NET Web API 2 和 ASP.NET Core 3.1 Web API 之间的行为不同?
Why different behavior between ASP.NET Web API 2 & ASP.NET Core 3.1 Web API?
我将以下数据发布到 2 个不同的 api 端点,一个在 ASP.NET Web API 2 应用程序中,另一个在 ASP.NET 中核心 3.1 Web API 应用程序。
var data = new Data
{
Key = "k1",
Value = 80
};
IClient httpClient = new FluentClient("http://localhost:46551/");
var x = httpClient.PostAsync("weatherforecast", data).GetAwaiter().GetResult();
对于两个 Web API 应用程序,我的模型 class 低于 Value
是 object
类型的位置,这是我的硬性要求,我不能接受实际类型。
public class Data
{
public string Key { get; set; }
public object Value { get; set; }
}
当我将数据发布到 ASP.NET Web API 2(使用 .Net 4.6.1)时,VS 调试器仅正确显示值而没有任何其他负载:
但对于 ASP.NET Core 3.1 Web API,VS 调试器显示如下,与 ValueKind
:
完全不同的表示
我需要将 data
写入 Json 格式,输出低于预期,
{ "Key":"k1", "Value":80 }
当我尝试为 ASP.NET Core 3.1 Web API 序列化 data
时,我得到了这个输出:
var ser = JsonConvert.SerializeObject(data);
{ "Key":"k1", "Value": {"ValueKind":4} }
对于 ASP.NET Web API 2 应用程序,虽然我得到了预期的输出。
问题,如何从 ASP.NET Core 3.1 应用程序获得此输出 { "Key":"k1", "Value":80 }
以及为什么两个应用程序的行为不同?
谢谢,
您以前使用过 Newtonsoft 吗? JSON 格式化程序现在包含在 netcore 3x 中是默认的,除非您明确包含另一个解析器,例如 NewtonSoft。 new/default 解析器的行为与 Newtonsoft 有很多不同,但在迁移时让我的团队最痛苦的是 System.Text.Json 解析器在识别 JSON 时不做假设.
这是最常见的情况,有时一个字段有时可能是一个复杂的 JSON 对象,并且在诸如布尔值或整数的情况下还包含原始类型。对我来说,一个具体的例子是一个设置概念,它基本上是一个 key/value 对,其中键是设置的名称,例如 GridSettings,它是一个 blob 并作为 JSON 存储在 Postgres 中,但是另一个设置是这样的因为 showHidden 是简单的 true 或 false。 Newtonsoft 仍然会将该布尔值强制转换为 JSON,因为支持模型和实体模型将其声明为 System.Text.Json 表示不,除非您另有说明,否则这只是一个布尔值。
尝试在 IoC/Startup 中注入 Newtonsoft 作为解析器,看看是否会改变行为。
关于新解析器差异的一些细节:
https://docs.microsoft.com/en-us/dotnet/core/compatibility/aspnetcore#authentication-newtonsoftjson-types-replaced
我们还必须在某些情况下对格式化程序进行调整:
自定义格式化程序:
https://code-maze.com/content-negotiation-dotnet-core/
总而言之,我确实认为不做任何假设的解析器意味着很好并且可能是一件好事。然而,就我而言,我们根本没有准备好进行所有必要的修正来抵消这种变化。因此现在,我们坚持使用旧的 Newtonsoft。
我将以下数据发布到 2 个不同的 api 端点,一个在 ASP.NET Web API 2 应用程序中,另一个在 ASP.NET 中核心 3.1 Web API 应用程序。
var data = new Data
{
Key = "k1",
Value = 80
};
IClient httpClient = new FluentClient("http://localhost:46551/");
var x = httpClient.PostAsync("weatherforecast", data).GetAwaiter().GetResult();
对于两个 Web API 应用程序,我的模型 class 低于 Value
是 object
类型的位置,这是我的硬性要求,我不能接受实际类型。
public class Data
{
public string Key { get; set; }
public object Value { get; set; }
}
当我将数据发布到 ASP.NET Web API 2(使用 .Net 4.6.1)时,VS 调试器仅正确显示值而没有任何其他负载:
但对于 ASP.NET Core 3.1 Web API,VS 调试器显示如下,与 ValueKind
:
我需要将 data
写入 Json 格式,输出低于预期,
{ "Key":"k1", "Value":80 }
当我尝试为 ASP.NET Core 3.1 Web API 序列化 data
时,我得到了这个输出:
var ser = JsonConvert.SerializeObject(data);
{ "Key":"k1", "Value": {"ValueKind":4} }
对于 ASP.NET Web API 2 应用程序,虽然我得到了预期的输出。
问题,如何从 ASP.NET Core 3.1 应用程序获得此输出 { "Key":"k1", "Value":80 }
以及为什么两个应用程序的行为不同?
谢谢,
您以前使用过 Newtonsoft 吗? JSON 格式化程序现在包含在 netcore 3x 中是默认的,除非您明确包含另一个解析器,例如 NewtonSoft。 new/default 解析器的行为与 Newtonsoft 有很多不同,但在迁移时让我的团队最痛苦的是 System.Text.Json 解析器在识别 JSON 时不做假设. 这是最常见的情况,有时一个字段有时可能是一个复杂的 JSON 对象,并且在诸如布尔值或整数的情况下还包含原始类型。对我来说,一个具体的例子是一个设置概念,它基本上是一个 key/value 对,其中键是设置的名称,例如 GridSettings,它是一个 blob 并作为 JSON 存储在 Postgres 中,但是另一个设置是这样的因为 showHidden 是简单的 true 或 false。 Newtonsoft 仍然会将该布尔值强制转换为 JSON,因为支持模型和实体模型将其声明为 System.Text.Json 表示不,除非您另有说明,否则这只是一个布尔值。
尝试在 IoC/Startup 中注入 Newtonsoft 作为解析器,看看是否会改变行为。
关于新解析器差异的一些细节: https://docs.microsoft.com/en-us/dotnet/core/compatibility/aspnetcore#authentication-newtonsoftjson-types-replaced
我们还必须在某些情况下对格式化程序进行调整:
自定义格式化程序: https://code-maze.com/content-negotiation-dotnet-core/
总而言之,我确实认为不做任何假设的解析器意味着很好并且可能是一件好事。然而,就我而言,我们根本没有准备好进行所有必要的修正来抵消这种变化。因此现在,我们坚持使用旧的 Newtonsoft。