如何将没有超时的订购商品发布到控制器

HTML5离线ASP.NET MVC4应用程序允许输入订单数量并为客户提交订单。

在浏览器中呈现的产品列表包含约4000个产品。 只订购了少量特定订单的产品。

使用下面的代码请求超时。 浏览器发布所有产品。 请求花费太多时间,可能由httpruntime ExecutionTimeout终止

服务器错误日志显示已收到所有发布的数据。 看起来MVC模型绑定器需要太多时间来从发布的数据创建产品列表。

如何解决这个问题? 如何仅发布已输入数量或其他想法的订购商品? 如果这是合理的话,我可以切换到ajax,jquery和MVC4 Web API。

控制器:

public class OfflineOrderController : ControllerBase { [HttpGet] public ActionResult Order(string customerId) { return View(new MobileOrderOrderViewModel(customerId)); } [HttpPost] public ActionResult Order(string customerId, [Bind(Prefix = "Products")] IEnumerable Result) { ... save order to database return new ContentResult() { Content = "Order received" }; } public AppCacheResult Manifest() { return new AppCacheResult(new[] { Url.Content("~/Image/Icon/favicon") }); } } 

视图:

    @using (Html.BeginForm()) {  @for (int i = 0; i < Model.Products.Count; i++) {  } 
@Model.Products[i].Id @Html.HiddenFor(m => Model.Products[i].Id) @Html.TextBoxFor(m => Model.Products[i].Quantity, new { type = "number", min = 0 })
@Html.HiddenFor(m => Model.CustomerId) }

视图模型:

 public class MobileOrderOrderViewModel : ViewModelBase { public string CustomerId { get; set; } public List Products { get; set; } public MobileOrderOrderViewModel( string customer ) { CustomerId = customer; ... populate Products property from database } } 

模型:

  public class OrderedItems { public string Id; public decimal Quantity; } 

UPDATE2

使用来自Imrans的代码回答我创建了API控制器来接收订购的产品:

  public class OrderController :ApiController { public HttpResponseMessage Post(string customerid, [FromBody]List products) { .... } } 

调试器显示产品已发布但产品参数为空列表。 如何将选定的产品列表传递给Web API?

用于发布的代码是:

  $(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 productIndex = $(element).prevAll()[1]; var productIdElement = $(element).prevAll()[0]; elementsToSend.push(productIndex); elementsToSend.push(productIdElement); elementsToSend.push(element); }); var dataToPost = $(elementsToSend).serializeArray(); $.post(BASE_URL + "api/Order?" + $.param({ customerid: $("#CustomerId").val() }), dataToPost); return false; }); })  

好的,我认为你的观点应该是这样的

    @using (Html.BeginForm()) {  @for (int i = 0; i < Model.Products.Count; i++) {  } 
@Model.Products[i].Id @Html.HiddenFor(m => Model.Products[i].Id) @Html.TextBoxFor(m => Model.Products[i].Quantity, new { @class="quantity", type = "number", min = 0 })
@Html.HiddenFor(m => Model.CustomerId) }

这是控制器方法:

 [HttpPost] public ActionResult Order(string customerId, List products) { ..... } 

希望这可以帮助。

您可以尝试使用AJAX来减少负载:

 $('form').submit(function () { var data = $(this).serializeArray().filter(function (k, v) { // Filter data based on order rule }); // Send AJAX! return false; }); 

请记住,这只会劫持默认的HTML表单行为。 它可以通过关闭JavaScript来取代。

编辑:确保您使用的是Controller / C#命名约定。 否则,绑定可能不起作用。

 orderedItems.push({ Id: items[i].Id, Quantity: items[i].Quantity }); var data = JSON.stringify({ customerId: $("customerId").val(), Result: orderedItems }); 

有更好的方法可以使用filter进行列表推导,但是你对我有意义。

最后,在Order POST操作中,最好返回一个JsonResult