web-dev-qa-db-fra.com

La désérialisation des types de référence sans constructeur sans paramètre n'est pas prise en charge

J'ai cette API

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

            return BadRequest();
        }

Et c'est mon modèle de demande

    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; }
    }

donc quand j'essaie de toucher l'API avec ce corps

{
        "partnerId": 101,
        "products": [{
            "productId": 100,
            "unitOfMeasureId": 102,
            "quantity":5
        }
     ]
}

il s'agit de la demande: System.NotSupportedException: la désérialisation des types de référence sans constructeur sans paramètre n'est pas prise en charge. Tapez 'Alati.Commerce.Sync.Api.Controllers.AddDocumentRequestModel'

Je n'ai pas besoin d'un constructeur sans paramètre, car il ne lit pas les paramètres du corps. Y a-t-il une autre façon de désérialiser?

2
Yoana Gancheva

Non, vous devez ajouter un constructeur par défaut et supprimer le modificateur private du set; méthode de la liste des produits et propriété PartnerId pour résoudre ce problème.

Ce correctif provoque cet avertissement CA2227: les propriétés de la collection doivent être en lecture seule , mais:

Vous pouvez supprimer l'avertissement si la propriété fait partie d'une classe DTO (Data Transfer Object).

Ensuite, vous pouvez ajouter un SuppressMessageAttribute :

public class AddDocumentRequestModel
{
    public 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; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage(
        category: "Usage", 
        checkId: "CA2227:Collection properties should be read only", 
        Justification = "Property is part of a Data Transfer Object (DTO) class.")]
    [Required, MustHaveOneElement(ErrorMessage = "At least one product is required")]
    public List<ProductRequestModel> Products { get; set; }
}
2
Joao Pedro