发布到 ASP.NET Core 3.1 Web 应用程序时,“[FromBody]MyClass 数据”通常为空

Gre*_*reg 5 c# asp.net-core razor-pages

我最近在从 .NET Core 2.2 升级到 3.1 后遇到了这个有趣(令人沮丧)的问题。以前,我会将数据 POST 到 Web 应用程序,接收方法如下所示:

public IActionResult OnPostAddNewDataAsync([FromBody]MyClass data)
{
    //...
}
Run Code Online (Sandbox Code Playgroud)

哪里MyClass可能是这样的:

public class MyClass
{
    public string Field1 {get; set;}
    public integer Value1 {get; set;}
}
Run Code Online (Sandbox Code Playgroud)

(作为参考,要从 Javascript 访问端点,您可以这样做:

 await PostDataAsync("AddNewData", {
      "Field1": "Hello I am",
      "Value1": 7
 });

async function PostDataAsync(handler, data)
{
    return await $.ajax({
        url: window.location.pathname + "?handler=" + handler,
        type: "POST",
        contentType: "application/json",
        headers:
        {
            RequestVerificationToken: $('input:hidden[name="__RequestVerificationToken"]').val()
        },
        data: JSON.stringify(data)
    });
}
Run Code Online (Sandbox Code Playgroud)

我花了一段时间才弄明白!)。

这工作得很好。

更新 .NET Core 3.1 后,我的许多 POST 方法停止工作,并且该[FromBody]值将为空。

注意:作为升级到 .NET Core 3.1 的一部分,我删除了对 的引用Newtonsoft.Json,而是决定尝试使用新的System.Text.Json. 这将变得很重要!

Gre*_*reg 13

如前所述,对 的引用已Newtonsoft.Json被删除,任何自动 Json 转换都由System.Text.Json. 事实证明,这是导致问题的原因,因为System.Text.Json它不够灵活(微软自己这么说,而且它的目的是这样:如何从 Newtonsoft.Json 迁移到 System.Text.Json)

在 .NET Core 3 之前,Newtonsoft.Json内部使用 ASP.NET Core ,现在System.Text.Json改为使用。

一个例子是数字字段,例如MyClass.Value1。如果从 Javascript 中传递“10”或 10,Newtonsoft.Json将处理该问题并将两者都识别为 10。System.Text.Json默认情况下,该字段不能有引号,如果在 Json 中发布了它,您将得到一个空[FromBody]值。

这个问题的最快解决方案是在Newtonsoft.Json这些情况下恢复到,这很容易通过:

  • 安装 Nuget 包 Microsoft.AspNetCore.Mvc.NewtonsoftJson
  • 在 Startup.cs 中,更新以下方法:

.

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages().AddNewtonsoftJson();

    //All your other code:
    //...
}
Run Code Online (Sandbox Code Playgroud)

这是直接取自这里

进行此更改后,一切都再次按预期工作。

我知道System.Text.Json可以配置自定义解析器来处理这些情况(我在其他地方使用过),但我有几十个 POST 方法,而不是更新所有这些方法以使用新方法,它更容易如上所述。