ASP.NET Web API Model Associating an Unclassified List of Complex Objects

I am trying to model the binding of a complex object to an inconsistent list using ApiController. All fields except the list are set correctly, but the list contains one element (although two list elements have been published), and the element is null. If I take the same code and point it to the MVC controller using the same type of parameter in my action method, everything will work as expected.

Since I use an inconsistent list, I use the ".Index" hidden entry as described by Phil Haack ( http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx )

ApiController also correctly links the list if I remove the ".Index" input and send the list as a sequential list starting with 0. (This option works for testing, but is not a great option in production, since list items can be added and removed by the user, so I want to use an unclassified list.)

I understand that web API controllers perform parameter binding differently than MVC controllers, as discussed here , but it seems that unclassified lists should correctly bind in web API controllers. Am I missing something? Why does the same code work for the MVC controller and not for the web API controller? How can I get invalid lists for proper binding in web API?

Here are the options for my post:

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 

Here is my web API management action:

(the request.BatchProductLots list is set to one element (although two elements have been published) and that one element is null)

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

Here is a complex list object that I am trying to associate with:

 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
source share
2 answers

The short answer is, this is not possible with the Web Api Model Binder. MVC and Web Api use different middleware, and the Web Api middleware only works on simple types.

See this answer for links that explain below, as well as possible solutions.

Answer longer, create a custom implementation of System.Web.Http.ModelBinding.IModelBinder and change the action signature to the following

 public Response Create([ModelBinder(CustomModelBinder)]BatchCreateRequest request) 
+1
source

Do you really need to install Index ? In this case, one of the possible solutions could be the Index part of the BatchProductLot class. The sequence of the list does not matter, and Web Api should be able to link it.

Another idea is to use the application/json content type and send JSON. You can use Json.Net to deserialize and bind the model.

Read Using Alternate JSON Serializer in ASP.NET Web Interface and even use this Nuget WebApi Json.NET MediaTypeFormatter package if you do not want to do manual wiring.

0
source

Source: https://habr.com/ru/post/1490760/


All Articles