ASP.NET Core Web API 模型绑定行为更改

ASP.NET Core Web API Model binding behavior change

我有一个简单的控制器,带有自定义模型类型标题 - 没有无参数构造函数和public setter

我在 asp.net mvc core 2.2 和 3.1 中尝试了以下代码。

型号class:

public class Heading
{
    public string Title { get; }
    public Heading(string title)
    {
        Title = title;
    }
}

API 控制器:

[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
    [HttpPost]
    public void Post([FromBody] Heading value)
    {
    }
}

使用 .net core 2.2,绑定工作完美。但是对于核心 3.1,它会抛出错误

System.NotSupportedException: Deserialization of reference types without parameterless constructor is not supported. Type 'WebApplication3.Controllers.Heading' at System.Text.Json.ThrowHelper.ThrowNotSupportedException_DeserializeCreateObjectDelegateIsNull(Type invalidType)

这是行为上的改变吗?还能实现吗?

ASP.NET Core 2.2 中,它可以正常工作只是因为 Newtonsoft.Json。在ASP.NET核心版本>=3.0中被System.Text.Json取代。 Here 更多关于 System.Text.Json,新的默认 ASP.NET 核心 JSON 序列化程序。

如果您想切换回以前默认使用 Newtonsoft.Json,请执行以下操作:

首先安装 Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet 包。然后在ConfigureServices()中添加对AddNewtonsoftJson()的调用如下:

public void ConfigureServices(IServiceCollection services)
{
     ...
     services.AddControllers()
          .AddNewtonsoftJson()
     ...
 }

更多详情:ASP.NET Core 3.0 - New JSON serialization

来自docs

复杂类型

A complex type must have a public default constructor and public writable properties to bind. When model binding occurs, the class is instantiated using the public default constructor.

您需要为绑定添加一个无参数构造函数才能使用该模型。

如果您使用的 NewtonsoftJson 可能允许无参数构造函数模型,则该行为可能在之前(2.2 和之前)对您有用。自 3.0 .NET Core uses the newer System.Text.Json serializer by default.

尽管您可以将默认序列化程序和 return 更改为 @TanvirArjel 提到的以前的功能 Newtonsoft.Json,但理想情况是使用默认序列化程序 System.Text,因为它具有更好的功能表现。你可以在这里查看: How to migrate from Newtonsoft.Json to System.Text.Json 错误是由于标题 class 没有无参数有效的构造函数引起的,应按如下方式定义。

public class Heading {
    Heading(){
    }
    public string AttrOne {get; set;}
    public string AttrTwo {get; set;}
}