c# - 在 IEnumerable View 中编辑数据(订单行的项目)

标签 c# entity-framework razor ienumerable

我的模型:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SNW.Models.CustomerOrderInfo
{
    public class MemberOrder : CustomerOrder
    {
        public new int customerOrderID { get; set; }
        [..]
        public int customerOrderLineID { get; set; }
        public int productID { get; set; }
        [..]
        public double customerOrderQtyMin { get; set; }
        public double customerOrderQtyMax { get; set; }
        [..]
    }
}

我的 Controller :

[..]
using SNW.Models;
using SNW.Models.CustomerOrderInfo;

namespace SNW.Controllers
{
    public class CustomerOrderController : Controller
    {
        private DBModelContainer db = new DBModelContainer();
        [HttpPost, ActionName("SaveChanges")]
        public ActionResult SaveChanges([Bind(Include = "customerOrderQtyMax")] SNW.Models.CustomerOrderInfo.MemberOrder line)
        {
            if(ModelState.IsValid)
            {
                    db.Entry(line).State = EntityState.Modified;
                    db.SaveChanges();
                    return RedirectToAction("CustomerOrder");
            }
            return View(line);
        }
    }
}

我的观点(CustomerOrder.cshtml):

@model IEnumerable<SNW.Models.CustomerOrderInfo.MemberOrder>
[..]
    @foreach (var MemberOrder in Model)
    {
    <tr>
        <td>@MemberOrder.productID</td>
        <td>@MemberOrder.productName</td>
        [..]
        <td>@Html.EditorFor(model => MemberOrder.customerOrderQtyMin)</td>
        <td>
            @using (Html.BeginForm("SaveChanges", "CustomerOrder", new { id = MemberOrder.customerOrderLineID }))
            {
                @Html.ValidationSummary(true)
                @Html.HiddenFor(model => MemberOrder.customerOrderLineID)
                @Html.EditorFor(model => MemberOrder.customerOrderQtyMax)
                @Html.ValidationMessageFor(model => MemberOrder.customerOrderQtyMax)
                <input type="submit" value="+" class="btn btn-default" />
            }
        </td>
    [..]
    </tr>

渲染 View :

问题:

每当我更改订单行的最大值并单击“+”以在数据库中更新它时,它都不起作用。

line SaveChanges() 中的值方法为 0 或 null,包括 customerOrderQtyMax值为 0.0,但数据库更新也没有发生 - 以前的值再次显示。

所以我的问题是,如何只传递 customerOrderQtyMax从此 IEnumerable View 向数据库输入值?我希望能够在 CustomerOrder.cshtml 页面中修改订单(或购物车,如果您愿意)值。

到目前为止我尝试了什么:

  1. Updating Related Data with the Entity Framework in an ASP.NET MVC Application

  2. Various tutorials on Youtube

  3. 比较 SaveChanges() Edit() 的方法EF6 从数据库模型为 CustomerOrderLines 生成的方法实体。后者不使用 IEnumerables<>,它有自己的 View (Edit.cshtml)。

  4. 添加了一个额外的 HiddenFor()我 View 中的字段,因为我的订单行的主键由 customerOrderLineID 组成和 customerOrderID属性。

@using (Html.BeginForm("SaveChanges", "CustomerOrder", new { id = MemberOrder.customerOrderLineID })) { @Html.ValidationSummary(true) @Html.HiddenFor(model => MemberOrder.customerOrderLineID) @Html.HiddenFor(model => MemberOrder.customerOrderID) @Html.EditorFor(model => MemberOrder.customerOrderQtyMax) @Html.ValidationMessageFor(model => MemberOrder.customerOrderQtyMax) <code><input type="submit" value="+" class="btn btn-default" /></code> }

谢谢你们的帮助,伙计们!

编辑:

我已经更改了 SaveChanges() 中的代码方法很多次,但这是我收到的错误:

  1. 引用SNW.Models.CustomerOrderInfo.MemberOrderpublic ActionResult SaveChanges([Bind(Include = "customerOrderQtyMax")] SNW.Models.CustomerOrderInfo.MemberOrder line)奖励我以下错误: {“实体类型 MemberOrder 不是当前上下文模型的一部分。” 可能是因为这是我自定义的模型,它继承自 CustomerOrder模型,因为
    • CustomerOrder可以被 EF 模型生成器覆盖
    • 我需要使用额外的自定义属性进行计算
  2. 已更改 SNW.Models.CustomerOrderInfo.MemberOrder到原文CustomerOrderLine并收到以下错误:{“存储更新、插入或删除语句影响了意外的行数 (0)。自加载实体以来,实体可能已被修改或删除。刷新 ObjectStateManager 条目。” .
    • CustomerOrderLine由 EF 模型生成器生成,我希望其属性与 CustomerOrder 合并能够在一个窗口中编辑订单信息,而不是为每一行(订单行)编辑 View 。这就是我定制 SNW.Models.CustomerOrderInfo.MemberOrder 的原因模型。
    • 现在 SaveChanges()public ActionResult SaveChanges([Bind(Include = "customerOrderQtyMax")] CustomerOrderLine line)
  3. @贾森。 HTTP POST header 谢谢。
Request URL:http://localhost:64778/CustomerOrder/SaveChanges/8
Request Method:POST
Status Code:500 Internal Server Error
Request Headersview parsed
POST /CustomerOrder/SaveChanges/8 HTTP/1.1
Host: localhost:64778
Connection: keep-alive
Content-Length: 68
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://localhost:64778
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://localhost:64778/CustomerOrder/CustomerOrder
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-GB,en;q=0.8,lt;q=0.6
Cookie: .ASPXFORMSAUTH=F44D36B23D1EA17ABB24DEEC4AFA7B09FD2D7B3EEB8D9C57D95561E9A9B334F4BA90F46AEAC2E2DE23958998B3F888342E507B92484C45D990CD0FD08D38F8D8D994CC8F5C231A0144DE4A7B89A286A1AFFEE765C86C856E71403FF94FDF873E
Form Dataview parsed
MemberOrder.customerOrderLineID=8&MemberOrder.customerOrderQtyMax=78
Response Headersview parsed
HTTP/1.1 500 Internal Server Error
Cache-Control: private
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcRG9uYXRhc1xTb3VyY2VcUmVwb3NcU291bmRzTmljZVdob2xlZm9vZHNcU05XXFNOV1xDdXN0b21lck9yZGVyXFNhdmVDaGFuZ2VzXDg=?=
X-Powered-By: ASP.NET
Date: Wed, 09 Apr 2014 21:03:23 GMT
Content-Length: 17180

HTML Form:

<form action="/CustomerOrder/SaveChanges/8" method="post"> <input data-val="true" data-val-number="The field customerOrderLineID must be a number." data-val-required="The customerOrderLineID field is required." id="MemberOrder_customerOrderLineID" name="MemberOrder.customerOrderLineID" type="hidden" value="8"> <input class="text-box single-line" data-val="true" data-val-number="The field customerOrderQtyMax must be a number." data-val-required="The customerOrderQtyMax field is required." id="MemberOrder_customerOrderQtyMax" name="MemberOrder.customerOrderQtyMax" type="text" value="3"> <span class="field-validation-valid" data-valmsg-for="MemberOrder.customerOrderQtyMax" data-valmsg-replace="true"></span><br/> <input type="submit" value="+" class="btn btn-default"> </form>

  1. Tried a solution from this StackOverflow answer and changed the code to [HttpPost, ActionName("SaveChanges")] public ActionResult SaveChanges([Bind(Include = "customerOrderQtyMax")] CustomerOrderLine line) // whitelist fields { CustomerOrderLine lineTemp = new CustomerOrderLine() { customerOrderQtyMax = line.customerOrderQtyMax }; if(ModelState.IsValid) { db.Entry(lineTemp).State = EntityState.Added; db.SaveChanges(); return RedirectToAction("CustomerOrder"); } return View(lineTemp); }

And now got this error: {"Cannot add or update a child row: a foreign key constraint fails (\"c1snw\".\"CustomerOrderLines\", CONSTRAINT \"FK_ProductCustomerOrderLine\" FOREIGN KEY (\"productID\") REFERENCES \"Products\" (\"productID\") ON DELETE NO ACTION ON UPDATE NO ACTION)"}, which probably means... well, I'm not sure if correct line is selected from DB using this code and whether it is trying to Update or Add a new line. Will check that.

SOLUTION:

@Jasen's suggestion of using Prefix="MemberOrder" in Bind helped to get code working!

However, I got rid of Include= statement in Bind, because it only worked when all line's attributes, that are not initially empty (null or 0) are included, and since I need all of them, I removed Include= in Controller and added more HiddenFor fields in the View. If I haven't had done this, Controller would attempt to change initial values to null) or 0.

Final code:

My Controller:

[HttpPost, ActionName("SaveChanges")]
public ActionResult SaveChanges([Bind(Prefix="MemberOrder")] CustomerOrderLine line) // whitelist fields
{
    if(ModelState.IsValid)
    {
            db.Entry(line).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("CustomerOrder");
    }
    return View(line);
}

我的看法:

@using (Html.BeginForm("SaveChanges", "CustomerOrder", new { id = MemberOrder.customerOrderLineID }))
{
    @Html.ValidationSummary(true)
    @Html.HiddenFor(model => MemberOrder.customerOrderLineID)
    @Html.HiddenFor(model => MemberOrder.customerOrderID)
    @Html.HiddenFor(model => MemberOrder.productID)
    @Html.HiddenFor(model => MemberOrder.customerOrderQtyMin)
    @Html.EditorFor(model => MemberOrder.customerOrderQtyMax)
    @Html.HiddenFor(model => MemberOrder.customerOrderQtyActual)
    @Html.ValidationMessageFor(model => MemberOrder.customerOrderQtyMax)
    <input type="submit" value="+" class="btn btn-default" />
}

关于类似问题的更多资源:

  1. ASP.NET MVC Model Binding - Part1 (CodeProject)

  2. How to use Bind Prefix? (StackOverflow)

  3. ASP.Net MVC3 Model Binding IEnumerable with Editor Template (StackOverflow)

  4. How to bind multiple prefixes? (ASP.NET)

  5. Multiple submit buttons with ASP.NET MVC: final solution

最佳答案

这里的关键问题是 for 循环弄乱了发布的变量名,因此自动绑定(bind)将失败。因此,您需要将 Prefix 参数添加到您的 Bind。

[Bind(Prefix="MemberOrder", ...)]

您在 View 的 EditorFor 帮助程序中指定的前缀:

@Html.EditorFor(model => MemberOrder.customerOrderQtyMax)

此外,将行 ID 添加到绑定(bind)包含。

[HttpPost, ActionName("SaveChanges")]
public ActionResult SaveChanges(
    [Bind(Prefix="MemberOrder", Include = "customerOrderLineID,customerOrderQtyMax")]
        SNW.Models.CustomerOrderInfo.MemberOrder line)
{
    if(ModelState.IsValid)
    {
        db.Entry(line).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("CustomerOrder");
    }
    return View(line);
}

关于c# - 在 IEnumerable View 中编辑数据(订单行的项目),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22970647/

相关文章:

html - MVC Razor View 中的下拉列表由于其下方的元素而未扩展

c# - 在极少数情况下,重定向到 ACS 并返回后 Cookie 为空

c# - 在数据库中插入数据的存储库或服务 - Entity Framework

c# - Asp.Net Core 中的@Html.Action

c# - 如何使 ASP.NET 使用 Owin OpenId Connect 库创建经过身份验证的 session ?

c# - 具有运算符+的对象的Linq SUM?

c# - 使用 Entity Framework 的 SQL 查询运行速度较慢,使用了错误的查询计划

c# - 具有 asp 网络标识的自定义实体(一对多)

razor - 如何在可重用 Razor 类库内的 Controller 中注入(inject)服务

c# - 如何允许用户在 PropertyGrid 中设置表达式来确定属性值