如何发布订货的商品不超时控制器(How to post ordered items without

2019-10-21 11:56发布

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

在浏览器中呈现的产品列表中包含约4000产品。 只有极少数产品订购特定的顺序。

使用以下请求超时代码。 浏览帖子的所有产品。 请求花费太多的时间和很可能是由的httpRuntime ExecutionTimeout终止

Server错误日志显示,所有发布的数据被接收。 它看起来像MVC模型绑定需要太多的时间来从发布的数据产品列表。

如何解决这一问题? 如何发布仅订购的商品,其数量被输入或其他的想法? 我可以切换到阿贾克斯,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) {
  ....
   }
}

调试器显示的产品发布,但产品参数为空表。 如何通过选择产品列表,网络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>

Answer 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)
{
    .....
}

希望这可以帮助。



Answer 2:

您可以尝试AJAX来降低负载:

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

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

编辑:请确保您使用的控制器/ C#命名约定。 否则,绑定可能无法正常工作。

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

有发烧友使用的方法做列表理解filter ,但你有什么对我来说很有意义。

最后,在您的Order POST操作,这是一个好主意,返回JsonResult



文章来源: How to post ordered items without timeout to controller