不支持没有无参数构造函数的引用类型的反序列化

Yoa*_*eva 21 serialization json-deserialization .net-core-3.0

我有这个 API

 public ActionResult AddDocument([FromBody]AddDocumentRequestModel documentRequestModel)
        {
            AddDocumentStatus documentState = _documentService.AddDocument(documentRequestModel, DocumentType.OutgoingPosShipment);
            if (documentState.IsSuccess)
                return Ok();

            return BadRequest();
        }
Run Code Online (Sandbox Code Playgroud)

这是我的请求模型

    public class AddDocumentRequestModel
    {
        public AddDocumentRequestModel(int partnerId, List<ProductRequestModel> products)
        {
            PartnerId = partnerId;
            Products = products;
        }

        [Range(1, int.MaxValue, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
        public int PartnerId { get; private set; }

        [Required, MustHaveOneElement(ErrorMessage = "At least one product is required")]
        public List<ProductRequestModel> Products { get; private set; }
    }
Run Code Online (Sandbox Code Playgroud)

所以当我试图用这个身体点击 API 时

{
        "partnerId": 101,
        "products": [{
            "productId": 100,
            "unitOfMeasureId": 102,
            "quantity":5
        }
     ]
}
Run Code Online (Sandbox Code Playgroud)

这是请求:System.NotSupportedException:不支持反序列化没有无参数构造函数的引用类型。输入“Alati.Commerce.Sync.Api.Controllers.AddDocumentRequestModel”

我不需要无参数构造函数,因为它不读取主体参数。还有其他反序列化方法吗?

Adr*_*sui 29

你可以达到你想要的结果。您需要切换到 NewtonsoftJson 序列化(来自 Microsoft.AspNetCore.Mvc.NewtonsoftJson 包)

在 Startup.cs 中的 ConfigureServices 方法中调用它:

    services.AddControllers().AddNewtonsoftJson();
Run Code Online (Sandbox Code Playgroud)

在此之后,您的构造函数将被反序列化调用。

额外信息:我使用的是 ASP Net Core 3.1

稍后编辑:我想提供更多关于此的信息,因为这似乎也可以通过使用 System.Text.Json 来实现,尽管自定义实现是必要的。来自jawa的答案指出,可以使用System.Text.Json通过创建自定义转换器(从JsonConverter继承)并将其注册到转换器集合(JsonSerializerOptions.Converters)来实现反序列化为不可变的类和结构,如下所示:

   public class ImmutablePointConverter : JsonConverter<ImmutablePoint>
   {
   ...
   }
Run Code Online (Sandbox Code Playgroud)

进而...

   var serializeOptions = new JsonSerializerOptions();
   serializeOptions.Converters.Add(new ImmutablePointConverter());
   serializeOptions.WriteIndented = true;
Run Code Online (Sandbox Code Playgroud)

  • 这个答案为我解决了这个问题 (2认同)
  • 只需确保为您正在使用的 .Net 或 .Net Core 框架安装正确版本的 Microsoft.AspNetCore.Mvc.NewtonsoftJson 即可。尝试安装 .Net Core 3.1 的 5.x 版本不起作用,但安装 3.1.x 版本却可以。{捂脸} (2认同)

IBR*_*BRA 25

以防万一有人遇到与我相同的问题,我正在使用abstract类,一旦删除了abstract关键字,一切就正常了。


Ali*_*Ali 6

只需在构造函数之前添加[JsonConstructor]如下内容:

public class Person
{
    public string Name { get; set; }
    public int LuckyNumber { get; private set; }
    
    [JsonConstructor]
    public Person(int luckyNumber)
    {
        LuckyNumber = luckyNumber;
    }
    public Person() { }
}
Run Code Online (Sandbox Code Playgroud)