ASP.NET MVC4 applications allows to enter ordered product quantities and passses them to Web API controller.
Controller receives empty product list as product parameter. Debugger shows that data is posted. How to refactor view so that products can passed to Web API ?
View:
@inherits ViewBase<MyApp.MobileOrderOrderViewModel>
<!DOCTYPE html>
<html>
<body>
@using (Html.BeginForm())
{
<table>
@for (int i = 0; i < Model.Products.Count; i++)
{
<tr>
<td>@Model.Products[i].Id</td>
<td>
@Html.HiddenFor(m => Model.Products[i].Id)
@Html.TextBoxFor(m => Model.Products[i].Quantity, new { @class="quantity", type = "number", min = 0 })
</td>
</tr>
}
</table>
<input type="submit" value="Send order">
@Html.HiddenFor(m => Model.CustomerId)
}
<script>
$(function () {
"use strict";
var BASE_URL = '@Url.Content("~/")';
$("form").submit(function (ev) {
var elementsToSend = [];
ev.preventDefault();
var quantityElements = $("input.quantity").filter(function (index, element) {
if ($(this).val() != 0) {
return true;
}
else {
return false;
}
});
$.each(quantityElements, function (index, element) {
var productIdElement = $(element).prevAll()[0];
elementsToSend.push(productIdElement);
elementsToSend.push(element);
});
var dataToPost = $(elementsToSend).serializeArray();
$.post(BASE_URL + "api/Order?" + $.param({
klient: $("#CustomerId").val()
}), dataToPost);
});
})
</script>
ViewModel:
public class MobileOrderOrderViewModel : ViewModelBase
{
public string CustomerId { get; set; }
public List<OrderedItems> Products { get; set; }
public MobileOrderOrderViewModel( string customer ) {
CustomerId = customer;
... populate Products property from database
}
}
Model:
public class OrderedItems
{
public string Id;
public decimal Quantity;
}
WebAPI Controller:
public class OrderController :ApiController
{
public HttpResponseMessage Post(string customerid, [FromBody]List<OrderedItems> products) {
// Why products.Count() is 0 here ?
...
}
}
Update
I changed code according to answer. alert() shows that string is in format described in answer but products parameter is still empty.
chrome shows that request type is
Content-Type:application/x-www-form-urlencoded;
but buffer contains json string. Maybe this confuses Web API. How to fix ?
$.each(quantityElements, function (index, element) {
var productIdElement = $(element).prevAll()[0];
var product = {
id: $(productIdElement).val(),
quantity: $(element).val()
};
elementsToSend.push(product);
});
var dataToPost = JSON.stringify(elementsToSend);
$.post(BASE_URL + "api/Order?" + $.param({
customerid: $("#CustomerId").val()
}), dataToPost);
The problem is with your data serialization.
In order to be properly binded it has to be in the following format:
In your case the following code produces a wrong output:
If I'am not wrong it produces something like:
You can fix this by something like:
Than instead of
serializeArray()
useJSON.stringify(products)
UPDATE
Try posting it to the server with:
P.S in this case you don't have to
stringify
products object because.$post
supports plain objects as well