Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MVC将复杂对象传递给控制器进行保存_C#_Asp.net Mvc - Fatal编程技术网

C# MVC将复杂对象传递给控制器进行保存

C# MVC将复杂对象传递给控制器进行保存,c#,asp.net-mvc,C#,Asp.net Mvc,我正在用MVC和实体框架写一个网页。 我有一个附加了行项目的订单,希望将复杂对象返回控制器进行处理 我现在已经包括了所有的代码 我的观点: @model BCMManci.ViewModels.OrderCreateGroup @{ ViewBag.Title = "Create"; } <h2>New Order</h2> @using (Html.BeginForm()) { @Html.AntiForgeryToken() <h4

我正在用MVC和实体框架写一个网页。 我有一个附加了行项目的订单,希望将复杂对象返回控制器进行处理

我现在已经包括了所有的代码

我的观点

@model BCMManci.ViewModels.OrderCreateGroup

@{
    ViewBag.Title = "Create";
}
<h2>New Order</h2>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <h4>@Html.DisplayFor(model => model.Order.Customer.FullName)</h4>

    <table>
        <tr>
            <td><b>Order Date:</b> @Html.DisplayFor(model => model.Order.OrderDate)</td>
            <td><b>Status:</b> @Html.DisplayFor(model => model.Order.OrderStatus.OrderStatusName)</td>
        </tr>
        <tr>
            <td colspan="2">
                <b>Notes</b>
                @Html.EditorFor(model => model.Order.Notes, new { htmlAttributes = new { @class = "form-control" } })
            </td>
        </tr>
    </table>
        @Html.ValidationMessageFor(model => model.Order.Notes, "", new { @class = "text-danger" })
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })


        <table class="table table-striped table-hover">
            <thead>
                <tr>
                    <td>Name</td>
                    <td>Price</td>
                    <td>Discount</td>
                    <td>Total</td>
                    <td>Quantity</td>
                </tr>
            </thead>
            <tbody>
                @foreach (var product in Model.ProductWithPrices)
                {
                    <tr>
                        <td>
                            @Html.DisplayFor(modelItem => product.ProductName)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => product.SellingPrice)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => product.DiscountPrice)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => product.TotalPrice)
                        </td>
                        <td>
                            @Html.EditorFor(modelItem => product.Quantity, new { htmlAttributes = new { @class = "form-control" } })
                        </td>
                    </tr>
                }
            </tbody>
        </table>

        <input type="submit" value="Create" class="btn btn-default" />
}
<div class="btn btn-danger">
    @Html.ActionLink("Cancel", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
[HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "Order,ProductWithPrices,Order.Note,product.Quantity")] OrderCreateGroup order)
    {
        try
        {
            if (ModelState.IsValid)
            {
                db.Orders.Add(order.Order);

                foreach (var orderItem in order.ProductWithPrices.Select(item => new OrderItem
                {
                    OrderId = order.Order.OrderId,
                    ProductId = item.ProductId,
                    Quantity = item.Quantity,
                    ItemPrice = item.SellingPrice,
                    ItemDiscount = item.DiscountPrice,
                    ItemTotal = item.TotalPrice
                }))
                {
                    db.OrderItems.Add(orderItem);
                }
                db.SaveChanges();
                return RedirectToAction("ConfirmOrder", new {id = order.Order.OrderId});
            }
        }
        catch (DataException /* dex */)
        {
            //TODO: Log the error (uncomment dex variable name and add a line here to write a log.
            ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
        }
        ViewBag.Products = db.Products.Where(model => model.IsActive == true);

        PopulateDropdownLists();
        return View(order);
    }
public class OrderCreateGroup
{
    public OrderCreateGroup()
    {
        ProductWithPrices = new List<ProductWithPrice>();
    }

    public Order Order { get; set; }
    public ICollection<ProductWithPrice> ProductWithPrices { get; set; }
}

public class ProductWithPrice : Product
{
    public decimal SellingPrice { get; set; }
    public decimal DiscountPrice { get; set; }

    public int Quantity { get; set; }

    public decimal TotalPrice { get; set; }
}
数据源

@model BCMManci.ViewModels.OrderCreateGroup

@{
    ViewBag.Title = "Create";
}
<h2>New Order</h2>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <h4>@Html.DisplayFor(model => model.Order.Customer.FullName)</h4>

    <table>
        <tr>
            <td><b>Order Date:</b> @Html.DisplayFor(model => model.Order.OrderDate)</td>
            <td><b>Status:</b> @Html.DisplayFor(model => model.Order.OrderStatus.OrderStatusName)</td>
        </tr>
        <tr>
            <td colspan="2">
                <b>Notes</b>
                @Html.EditorFor(model => model.Order.Notes, new { htmlAttributes = new { @class = "form-control" } })
            </td>
        </tr>
    </table>
        @Html.ValidationMessageFor(model => model.Order.Notes, "", new { @class = "text-danger" })
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })


        <table class="table table-striped table-hover">
            <thead>
                <tr>
                    <td>Name</td>
                    <td>Price</td>
                    <td>Discount</td>
                    <td>Total</td>
                    <td>Quantity</td>
                </tr>
            </thead>
            <tbody>
                @foreach (var product in Model.ProductWithPrices)
                {
                    <tr>
                        <td>
                            @Html.DisplayFor(modelItem => product.ProductName)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => product.SellingPrice)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => product.DiscountPrice)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => product.TotalPrice)
                        </td>
                        <td>
                            @Html.EditorFor(modelItem => product.Quantity, new { htmlAttributes = new { @class = "form-control" } })
                        </td>
                    </tr>
                }
            </tbody>
        </table>

        <input type="submit" value="Create" class="btn btn-default" />
}
<div class="btn btn-danger">
    @Html.ActionLink("Cancel", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
[HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "Order,ProductWithPrices,Order.Note,product.Quantity")] OrderCreateGroup order)
    {
        try
        {
            if (ModelState.IsValid)
            {
                db.Orders.Add(order.Order);

                foreach (var orderItem in order.ProductWithPrices.Select(item => new OrderItem
                {
                    OrderId = order.Order.OrderId,
                    ProductId = item.ProductId,
                    Quantity = item.Quantity,
                    ItemPrice = item.SellingPrice,
                    ItemDiscount = item.DiscountPrice,
                    ItemTotal = item.TotalPrice
                }))
                {
                    db.OrderItems.Add(orderItem);
                }
                db.SaveChanges();
                return RedirectToAction("ConfirmOrder", new {id = order.Order.OrderId});
            }
        }
        catch (DataException /* dex */)
        {
            //TODO: Log the error (uncomment dex variable name and add a line here to write a log.
            ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
        }
        ViewBag.Products = db.Products.Where(model => model.IsActive == true);

        PopulateDropdownLists();
        return View(order);
    }
public class OrderCreateGroup
{
    public OrderCreateGroup()
    {
        ProductWithPrices = new List<ProductWithPrice>();
    }

    public Order Order { get; set; }
    public ICollection<ProductWithPrice> ProductWithPrices { get; set; }
}

public class ProductWithPrice : Product
{
    public decimal SellingPrice { get; set; }
    public decimal DiscountPrice { get; set; }

    public int Quantity { get; set; }

    public decimal TotalPrice { get; set; }
}
这是控制器,但它现在没有意义,因为在页面的数据源中传递了参数

public ActionResult Create(OrderCreateGroup orderCreateGoup)

请,您能告诉我执行此操作的最佳方法吗?

在您的
OrderCreateGroup
类中,将集合初始化为空列表

public class OrderCreateGroup
{
    public OrderCreateGroup()
    {
       ProductWithPrices = new List<ProductWithPrice>();
    }
    public Order Order { get; set; }
    public ICollection<ProductWithPrice> ProductWithPrices { get; set; }
}
公共类OrderCreateGroup
{
public OrderCreateGroup()
{
ProductWithPrices=新列表();
}
公共秩序{get;set;}
公共ICollection ProductWithPrices{get;set;}
}
您需要添加
@Html.HiddenFor(m=>m.SellingPrice)
,如果要将它们发回控制器,则需要添加使用DisplayFor的其他绑定字段

@Html.ActionLink("Create", "Create", "Orders", new { orderCreateGoup = Model }, null)

注意:为了方便您,在浏览器中呈现页面时,请尝试查看生成的HTML代码,并查看带有名称属性的
标记中生成了哪些标记。

确保从复杂对象绑定了适当的属性,如下所示:

@model  BCMManci.ViewModels.OrderCreateGroup

...
@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">


        ...
        <div class="form-group">
            @Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.OrderCreateGroup.Order.Quantity, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.OrderCreateGroup.Order.Quantity, "", new { @class = "text-danger" })
            </div>
        </div>



        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>
@model BCMManci.ViewModels.OrderCreateGroup
...
@使用(Html.BeginForm())
{
@Html.AntiForgeryToken()
...
@LabelFor(model=>model.LastName,htmlAttributes:new{@class=“controllabel col-md-2”})
@EditorFor(model=>model.OrderCreateGroup.Order.Quantity,new{htmlAttributes=new{@class=“form control”})
@Html.ValidationMessageFor(model=>model.OrderCreateGroup.Order.Quantity,“,新的{@class=“text danger”})
}
@ActionLink(“返回列表”、“索引”)
注意:model.OrderCreateGroup.Order.Quantity将是订单的属性之一。
希望这能有所帮助。

请发布视图的所有代码。这是因为您没有在表单中正确生成表单控件(但您没有费心显示代码!)我已尝试实现您的建议。但是,由于数据源是OrderCreateGroup,我使用的是:
model.Order.Notes
而不是
model.OrderCreateGroup.Order.Notes
。它不允许我把这个放进去。这是否意味着我的数据源设置不正确?谢谢。价格不返回空值的已排序产品。但是,它们仍然是空的。嘿@ColinGenricks问题是您的价格必须使用DisplayFor查看。DisplayFor不会将值发回控制器。对于需要发回控制器的每个price属性,都需要一个@Html.HiddenFor()。谢谢。这就是问题所在。我添加了隐藏字段,现在这些值正在为订单执行