【问题标题】:ASP.NET Web API model binding non-sequential list of complex objectsASP.NET Web API 模型绑定复杂对象的非顺序列表
【发布时间】:2013-07-08 17:08:59
【问题描述】:

我正在尝试使用 ApiController 对具有非顺序列表的复杂对象进行建模。除列表之外的所有字段均设置正确,但列表包含一个元素(即使发布了两个列表元素)并且该元素为空。如果我采用完全相同的代码并将其指向在我的操作方法中使用相同参数类型的 MVC 控制器,那么一切都会按预期工作。

由于我使用的是非顺序列表,因此我使用 Phil Haack (http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx) 所描述的隐藏“.Index”输入

如果我删除“.Index”输入并将列表作为从 0 开始的顺序列表发送,ApiController 也会正确绑定列表。(此选项适用于测试,但在生产中作为列表项不是一个很好的选项可以由用户添加和删除,这就是我要使用非顺序列表的原因。)

我了解 Web API 控制器的参数绑定与 here 讨论的 MVC 控制器不同,但似乎非顺序列表应该在 Web API 控制器中正确绑定。我错过了什么吗?为什么相同的代码适用于 MVC 控制器而不适用于 Web API 控制器?如何在 Web API 中正确绑定非顺序列表?

这是我的帖子参数:

Parameters application/x-www-form-urlencoded

BatchProductLots.Index  1
BatchProductLots.Index  2
BatchProductLots[1].BrandId     1
BatchProductLots[1].ContainerId 9
BatchProductLots[1].ContainerLot    123
BatchProductLots[1].PackageId   2
BatchProductLots[1].PlannedQuantity 0
BatchProductLots[1].ProducedQuantity    20
BatchProductLots[2].BrandId     1
BatchProductLots[2].ContainerId 9
BatchProductLots[2].ContainerLot    123
BatchProductLots[2].PackageId   1
BatchProductLots[2].PlannedQuantity 0
BatchProductLots[2].ProducedQuantity    1
BatchStatusId   1
LotNumber   070313
ProductionDate  07/03/2013
RecipeId    1
RecipeQuantity  1
SauceId 22
X-Requested-With    XMLHttpRequest 

这是我的 Web API 控制器操作:

(request.BatchProductLots 列表设置为一个元素(即使发布了两个元素)并且该元素为空)

public Response Create(BatchCreateRequest request)
{
    Response response = new Response();

    try
    {
        Batch batch = Mapper.Map<Batch>(request);
        batchService.Save(batch);
        response.Success = true;
    }
    catch (Exception ex)
    {
        response.Message = ex.Message;
        response.Success = false;
    }

    return response;
}

这是我尝试绑定到的带有列表的复杂对象:

public class BatchCreateRequest
{
    public int BatchStatusId { get; set; }
    public DateTime ProductionDate { get; set; }
    public string LotNumber { get; set; }
    public int SauceId { get; set; }
    public int RecipeId { get; set; }
    public int RecipeQuantity { get; set; }
    public List<BatchProductLot> BatchProductLots { get; set; }

    public class BatchProductLot
    {
        public int BrandId { get; set; }
        public int ContainerId { get; set; }
        public string ContainerLot { get; set; }
        public int PackageId { get; set; }
        public int PlannedQuantity { get; set; }
        public int ProducedQuantity { get; set; }
    }
}

【问题讨论】:

    标签: c# asp.net asp.net-web-api model-binding asp.net-web-api2


    【解决方案1】:

    简短的回答,使用 Web Api 的模型绑定器是不可能的。 MVC 和 Web Api 使用不同的模型绑定器,而 Web Api 模型绑定器仅适用于简单类型。

    请参阅this answer 以获得进一步解释的链接以及可能的解决方案。

    更长的答案,创建 System.Web.Http.ModelBinding.IModelBinder 的自定义实现并将您的 Action 签名更改为以下内容

    public Response Create([ModelBinder(CustomModelBinder)]BatchCreateRequest request)
    

    【讨论】:

      【解决方案2】:

      您真的需要设置Index 吗?在这种情况下,一种可能的解决方案是使Index 成为BatchProductLot 类的一部分。那么列表的顺序就无所谓了,Web Api应该可以绑定它。

      另一个想法是使用 application/json 内容类型并发送 JSON。您可以使用 Json.Net 进行反序列化和模型绑定。

      阅读 Using an alternate JSON Serializer in ASP.NET Web API,如果您不想手动接线,甚至可以使用这个 Nuget 包 WebApi Json.NET MediaTypeFormatter

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-03-28
        • 2017-07-16
        • 1970-01-01
        • 1970-01-01
        • 2014-01-25
        • 1970-01-01
        相关资源
        最近更新 更多