首页 > 解决方案 > 提交后删除 URL ID?(ASP.NET/实体框架)

问题描述

我有一个允许用户添加和确认订单的程序。在一页上是所有订单(已确认和未确认)的表格。每个订单位于表格的每一行,每个订单行都有一个“确认订单”按钮,一旦点击,用户就会重定向到一个新视图,然后用户可以在其中添加这个特定的订单详细信息 - 单个order 可以由多行组成,所有行最终构成一个 order。订单中的每一行都有一个产品名称、数量、价格和供应商——这些属性中的三个(产品名称、数量和供应商)由用户使用位于开始表单中的输入来选择。

我做了什么:

我正在使用 onclick location.href 事件将单击的按钮 ID 传递给相关的操作结果:

onclick="location.href = '@Url.Action("ConfirmOrderPage","Home", new { id = order.OrderID })'"

order.OrderID 是使用 foreach 循环创建的,该循环为每个“确认订单”按钮动态分配一个 ID - 因此单击的按钮的 ID 将是用户希望确认的订单的 ID。

以下操作结果是将 id 发送到的位置:

public ActionResult ConfirmOrderPage(int id)
        {
            //Disable Lazy Loading
            DBAccessor.Configuration.ProxyCreationEnabled = false;

            //Clear list
            confirmedOrder.Clear();

            //Create dyanmic object reader that includes all related attributes
            var confirmedDynamicReader = DBAccessor.OrderLine.Where(bb => bb.OrderID == id).Include(zz => zz.Product).Include(aa => aa.Supplier);

            foreach (var confirmedOrderItem in confirmedDynamicReader)
            {
                //Load relevant attributes into view order table
                ConfirmOrderLineViewModel DisplayConfirmedOrders = new ConfirmOrderLineViewModel();
                DisplayConfirmedOrders.OrderID = confirmedOrderItem.OrderID;
                DisplayConfirmedOrders.ProductID = confirmedOrderItem.Product.ProductID;
                DisplayConfirmedOrders.ProductName = confirmedOrderItem.Product.Name;
                DisplayConfirmedOrders.Quantity = confirmedOrderItem.Quantity;
                DisplayConfirmedOrders.Price = confirmedOrderItem.Product.Price;
                DisplayConfirmedOrders.SupplierID = confirmedOrderItem.Supplier.SupplierID;
                DisplayConfirmedOrders.SupplierName = confirmedOrderItem.Supplier.Name;
                confirmedOrder.Add(DisplayConfirmedOrders);
            }

            //Return orderList with fetched attributes
            return View(confirmedOrder);
        }

我在 LINQ 表达式中使用传递的 id 来告诉 DBAccessor 我们当前正在使用哪个顺序。之后,我通过创建视图模型的对象 (ConfirmOrderLineViewModel) 将视图模型属性与 SQL 数据库中的属性相关联。

此外,我将列表“confirmedOrder”返回到视图 - 此列表是全局创建的,如下所示:

public static List<ConfirmOrderLineViewModel> confirmedOrder = new List<ConfirmOrderLineViewModel>();

其次,我正在使用一个额外的操作结果将传递的输入值(从开始表单)分配给数据库属性,之后我将重定向到上面看到的视图:

[HttpPost]
        public ActionResult SendOrderActionFinal(int id, int Product, int Quantity, int Supplier)
        {
            OrderLine newOrderLine = new OrderLine();
            newOrderLine.OrderID = id;
            newOrderLine.ProductID = Product;
            newOrderLine.Quantity = Quantity;
            newOrderLine.SupplierID = Supplier;
            DBAccessor.OrderLine.Add(newOrderLine);
            DBAccessor.SaveChanges();
            return RedirectToAction("ConfirmOrderPage");
        }

最后,从我的观点可以看出,我正在使用 HTML 开始表单以及几个 HTML 助手来获取用户输入,然后可以在提交表单后将其发送到操作结果。

我的开始形式如下:

<div class="confirmOrderLineItem">
    @using (Html.BeginForm("SendOrderActionFinal", "Home", new { id = Url.RequestContext.RouteData.Values["id"] }, FormMethod.Post))
    {
        var currentOrder = Url.RequestContext.RouteData.Values["id"];
        <div class="jumbotron">
            <h1>Confirm Order</h1>
            <p class="lead">Viewing Order Number: @currentOrder</p> 
        </div>
        <label>Product</label>
        @Html.DropDownList("Product", ViewBag.ProductList as SelectList, "Select Product", new { @class = "form-control", required = "required" })
        <br />
        <label>Quantity</label>
        @Html.TextBox("Quantity", null, new { @class = "form-control", @type = "number", required = "required", min = 1 });
        <br />
        <label>Supplier</label>
        @Html.DropDownList("Supplier", ViewBag.SupplierList as SelectList, "Select Supplier", new { @class = "form-control", @id = "Supplier" })
        <br />
        <button class="btn btn-success" type="submit" id="insertOrderBtn">Insert</button><button class="btn btn-primary" type="submit">Send Order</button>
    }
</div>

在开始表单的底部,您可以看到有两个提交按钮,一个名为“插入”,另一个名为“发送订单” - 单击“插入”时,当前输入的输入(在开始表单内)应该是添加到表中,如下所示,不对数据库本身进行任何提交(用户应该能够返回到主视图并且表应该被完全丢弃)。但是,当单击“发送订单”时,需要将整个表格内容提交到数据库。

桌子:

<table class="table">
    <thead class="thead-dark">
        <tr>
            <th scope="col">Product</th>
            <th scope="col">Quantity</th>
            <th scope="col">Price (R)</th>
            <th scope="col">Supplier</th>
        </tr>
    </thead>
    <tbody>
        @foreach (U18043039_HW6.ViewModels.ConfirmOrderLineViewModel confirmedOrder in Model)
        {
            <tr>
                <th>@confirmedOrder.ProductName</th>
                <td>@confirmedOrder.Quantity</td>
                <td>@confirmedOrder.Price</td>
                <td>@confirmedOrder.SupplierName </td>
            </tr>
        }
    </tbody>
</table>

我的问题是:

每当我单击“插入”或“发送订单”时,我都会遇到“/'应用程序中的服务器错误”错误 - 说“参数字典包含不可为空类型的参数 'id' 的空条目'System.Int32' for method 'System.Web.Mvc.ActionResult ConfirmOrderPage(Int32)'" 表示一旦提交表单,发送到 ConfirmOrderPage ActionResult 的 id 值将变为 null。为什么会这样?订单确实提交到数据库,并且表已更新 - 但是,只有当我自己返回并刷新页面时。

标签: c#asp.netasp.net-mvcentity-frameworklinq

解决方案


return RedirectToAction("ConfirmOrderPage");缺少对象 RouteValues 尝试因为您的 return RedirectToAction("ConfirmOrderPage", new { id = id }); ActionResult ConfirmOrderPage 需要一个 int 参数


推荐阅读