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<OrderedItems> Result)
{
... save order to database
return new ContentResult() { Content = "Order received" };
}
public AppCacheResult Manifest()
{
return new AppCacheResult(new[] {
Url.Content("~/Image/Icon/favicon")
});
}
}
查看:
<!DOCTYPE html>
<html manifest="~/MobileOrder/Manifest">
<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 { type = "number", min = 0 })
</td>
</tr>
}
</table>
<input type="submit" value="Send order">
@Html.HiddenFor(m => Model.CustomerId)
}
</body>
</html>
视图模型:
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
}
}
型号:
public class OrderedItems
{
public string Id;
public decimal Quantity;
}
UPDATE2
使用Imrans的代码回答我创建了API控制器来接收订购的产品:
public class OrderController :ApiController
{
public HttpResponseMessage Post(string customerid, [FromBody]List<OrderedItems> products) {
....
}
}
调试器显示产品已过帐但产品参数为空列表。 如何将选定的产品列表传递给Web API?
用于发布的代码是:
<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 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;
});
})
</script>
答案 0 :(得分:1)
好的,我认为您的观点应该是这样的
<!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>
<input type="hidden" name="Products.Index" value="@i"/>
@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() {
$("form").submit(function () {
var elementsToSend = [];
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);
});
elementsToSend.push($("#CustomerId")[0]);
var dataToPost = $(elementsToSend).serializeArray();
//send elementsToSend via ajax
$.post("/OfflineOrder/Order", dataToPost);
return false;
});
})
</script>
</body>
</html>
这是控制器方法:
[HttpPost]
public ActionResult Order(string customerId, List<OrderedItems> products)
{
.....
}
希望这有帮助。
答案 1 :(得分:0)
您可以尝试使用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
。