4

Я пытаюсь смоделировать привязку сложного объекта с помощью несекретного списка с помощью ApiController. Все поля, за исключением списка, установлены правильно, но список содержит один элемент (хотя два элемента списка были опубликованы), а элемент имеет значение null. Если я возьму тот же самый код и укажу его на MVC-контроллер, используя тот же тип параметра в моем методе действий, все работает так, как ожидалось.ASP.NET Web API-модель, связывающая несекретный список сложных объектов

Поскольку я с помощью непоследовательного списка, я использую скрытый вход «.index», как описано Филы Хаак (http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx)

ApiController также связывает список правильно ли я удалить».index «введите и отправьте список как последовательный список, начинающийся с 0. (Этот параметр работает для тестирования, но не является отличным вариантом в производстве, поскольку элементы списка могут быть добавлены и удалены пользователем, поэтому я хочу использовать не-последовательный список.)

Я понимаю, что API-интерфейсы API-интерфейсов имеют привязку параметров по-разному, чем MVC-контроллеры, как обсуждалось here, но это похоже на несекретные списки sh ould правильно связывается с контроллерами веб-API. Я что-то упускаю? Почему один и тот же код работает для контроллера MVC, а не для контроллера веб-API? Как я могу получить неверные списки для правильной привязки в веб-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; } 
    } 
} 

ответ

1

Короткий ответ, это не представляется возможным с помощью Web API в модели подшивки. MVC и Web Api используют разные связующие компоненты, а связующее устройство Web Api работает только на простых типах.

См. this answer для ссылок, которые поясняют ниже, а также Возможные ошибки.

Более длинный ответ, создать пользовательскую реализацию System.Web.Http.ModelBinding.IModelBinder и изменить сигнатуру ваших действий на следующий

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

вам действительно нужно сделать, чтобы 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, если вы не хотите делать проводку вручную.

Смежные вопросы