4

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

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

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

我知道 Web API 控制器的参数绑定与此处讨论的 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; }
    }
}
4

2 回答 2

1

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

有关进一步解释以及可能的解决方案的链接,请参阅此答案

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

public Response Create([ModelBinder(CustomModelBinder)]BatchCreateRequest request)
于 2014-08-21T19:38:13.140 回答
0

你真的需要Index设置吗?在这种情况下,一种可能的解决方案可能是成为课程Index的一部分BatchProductLot。列表的顺序无关紧要,Web Api 应该能够绑定它。

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

阅读在 ASP.NET Web API 中使用备用 JSON 序列化程序,如果您不想手动接线,甚至可以使用这个 Nuget 包WebApi Json.NET MediaTypeFormatter 。

于 2014-08-27T21:08:58.883 回答