繁体   English   中英

模型没有在post方法中传递,后者应该从更改的表单输入值更新实体

[英]Model not being passed in post method which should update entities from changed form input values

我的模型包含两个Order实体类型列表,但仅区分Status属性的值。 创建Orders ,status属性将自动设置为In Progress并在AdminOrders view ,放置在Orders In Progress table AdminOrders view有两个表: Orders In Progress tableOrders Dispatched table ,它们将分别由Model列表填充。

当新订单的Status值从下拉列表更改为已dispatched ,并且单击视图中的update按钮时,应触发帖子请求 - 将模型传递给它。 但是,当我调试AdminOrders post方法时,model参数为null。

这是Model类:

public class AdminOrdersViewModel
{
    public List<Order> OrdersInProgress { get; set; }
    public List<Order> OrdersDespatched { get; set; }
}

这些是控制器动作:

[HttpGet]
[Authorize(Roles = "Admin")]
public ActionResult AdminOrders()
{
    var model = db.Orders.Where(o => o.Status == "In Progress").ToList();
    var model2 = db.Orders.Where(o => o.Status == "Despatched").ToList();

    return View(new AdminOrdersViewModel { OrdersInProgress = model, OrdersDespatched = model2 });
}

[HttpPost]
[Authorize(Roles = "Admin")]
public async Task<ActionResult> AdminOrders([Bind(Include = "OrdersInProgress, OrdersDespatched")] AdminOrdersViewModel model)
{
    if (ModelState.IsValid)
    {
        foreach (var item in model.OrdersDespatched)
        {
            db.Entry(item).State = EntityState.Modified;
        }

        foreach (var item2 in model.OrdersInProgress)
        {
            db.Entry(item2).State = EntityState.Modified;
        }

        await db.SaveChangesAsync();

        var ordersInProgress = db.Orders.Where(o => o.Status == "In Progress").ToList();
        var ordersDespatched = db.Orders.Where(o => o.Status == "Despatched").ToList();

        return View(new AdminOrdersViewModel { OrdersDespatched = ordersDespatched, OrdersInProgress = ordersInProgress });
    }

    return View(model);
}

Get request AdminOrders方法中,每个Model列表的实体都会更新,并且在返回View时会向View提供一个新Model,因此页面应该更新,Orders会根据status属性移动到正确的表。 但是模型保留为null。

视图中的表单将View的模型分配给Post方法模型参数:

@using (Html.BeginForm("AdminOrders", "Manage", new { model = Model }, FormMethod.Post, new
    {
        enctype = "multipart/form-data"
    }))
    {
   }

我还试图在Post方法中传入两个新列表,并在表单请求中单独分配模型列表,但是接收错误。 如何确保Post请求将更新的模型传递给AdminOrders post方法?

完整的View页面代码如下:

@model ValueVille.Models.AdminOrdersViewModel

@{
    ViewBag.Title = "Orders";

}

<div class="main-content-container">

    <h1>New Orders In Progress</h1>
@using (Html.BeginForm("AdminOrders", "Manage", new { model = Model }, FormMethod.Post, new
{
    enctype = "multipart/form-data"
}))
{
        @Html.AntiForgeryToken()

        <table class="panel panel-default table cart-table">
            <tr>
                <th>
                    Order ID
                </th>
                <th>
                    Total
                </th>
                <th>
                    Date
                </th>
                <th>
                    Status
                </th>
            </tr>
            @foreach (var item in Model.OrdersInProgress)
            {
                <tr>
                    <td>
                        <a href="@Url.Action("OrderDetails", "Home", new { id = item.OrderId })">
                            @item.OrderId
                        </a>
                    </td>
                    <td>
                        £@item.Total
                    </td>
                    <td>
                        @item.OrderDate
                    </td>
                    <td>
                        @{
                            List<SelectListItem> listItems = new List<SelectListItem>();
                            listItems.Add(new SelectListItem
                            {
                                Text = item.Status,
                                Value = "Option1"
                            });
                            listItems.Add(new SelectListItem
                            {
                                Text = "Despatched",
                                Value = "Option2",

                            });

                        }

                        @Html.DropDownListFor(m => item.Status, listItems, item.Status)
                    </td>
                </tr>
                            }

        </table>

        <h1>Orders Despatched</h1>

        <table class="panel panel-default table cart-table">
            <tr>
                <th>
                    Order ID
                </th>
                <th>
                    Total
                </th>
                <th>
                    Date
                </th>
                <th>
                    Status
                </th>
            </tr>
            @foreach (var item in Model.OrdersDespatched)
            {
                <tr>
                    <td>
                        <a href="@Url.Action("OrderDetails", "Home", new { id = item.OrderId })">
                            @item.OrderId
                        </a>
                    </td>
                    <td>
                        £@item.Total
                    </td>
                    <td>
                        @item.OrderDate
                    </td>
                    <td>
                        @{
                            List<SelectListItem> listItems = new List<SelectListItem>();
                            listItems.Add(new SelectListItem
                            {
                                Text = item.Status,
                                Value = "Option1"
                            });
                            listItems.Add(new SelectListItem
                            {
                                Text = "Despatched",
                                Value = "Option2",

                            });

                        }

                        @Html.DropDownListFor(m => item.Status, listItems)
                    </td>
                </tr>
                            }

        </table>

        <div class="panel-body form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Update" class="btn btn-success" />
            </div>
        </div>

                            }



</div>

将ViewModel修改为:

public class AdminOrdersViewModel
{
    public List<Order> OrdersInProgress { get; set; }
    public List<Order> OrdersDespatched { get; set; }
    public List<Status> OrderStatuses { get; set; }
}

你的观点现在看起来像:

@model ValueVille.Models.AdminOrdersViewModel
@{
    ViewBag.Title = "Orders";
}

<div class="main-content-container">
    <h1>New Orders In Progress</h1>
    @using (Html.BeginForm("AdminOrders", "Manage", FormMethod.Post, new { enctype = "multipart/form-data" }))
    {
        @Html.AntiForgeryToken()

        <table class="panel panel-default table cart-table">
            <thead>
                <tr>
                    <th>Order ID</th>
                    <th>Total</th>
                    <th>Date</th>
                    <th>Status</th>
                </tr>
            </thead>
            <tbody>
                @for (int i = 0; i < Model.OrdersInProgress.Count(); i++)
                {
                    <tr>
                        <td>
                            <a href="@Url.Action("OrderDetails", "Home", new { id = Model.OrdersInProgress[i].OrderId })">@Model.OrdersInProgress[i].OrderId</a>
                            @Html.HiddenFor(x => x.Model.OrdersInProgress[i].OrderId)
                        </td>
                        <td>
                            £@Model.OrdersInProgress[i].Total
                            @Html.HiddenFor(x => x.Model.OrdersInProgress[i].Total)
                        </td>
                        <td>
                            @Model.OrdersInProgress[i].OrderDate
                            @Html.HiddenFor(x => x.Model.OrdersInProgress[i].OrderDate)
                        </td>
                        <td>
                            @Html.DropDownListFor(m => Model.OrdersInProgress[i].Status, new SelectList(Model.OrderStatuses, "Id", "StatusName"))
                        </td>
                    </tr>
                }
            </tbody>
        </table>

        <h1>Orders Despatched</h1>
        <table class="panel panel-default table cart-table">
            <thead>
                <tr>
                    <th>Order ID</th>
                    <th>Total</th>
                    <th>Date</th>
                    <th>Status</th>
                </tr>
            </thead>
            <tbody>
                @for (int i = 0; i < Model.OrdersDespatched.Count(); i++)
                {
                    <tr>
                        <td>
                            <a href="@Url.Action("OrderDetails", "Home", new { id = Model.OrdersDespatched[i].OrderId })">@Model.OrdersDespatched[i].OrderId</a>
                            @Html.HiddenFor(x => x.Model.OrdersDespatched[i].OrderId)
                        </td>
                        <td>
                            £@Model.OrdersDespatched[i].Total
                            @Html.HiddenFor(x => x.Model.OrdersDespatched[i].Total)
                        </td>
                        <td>
                            @Model.OrdersDespatched[i].OrderDate
                            @Html.HiddenFor(x => x.Model.OrdersDespatched[i].OrderDate)
                        </td>
                        <td>
                            @Html.DropDownListFor(m => Model.OrdersDespatched[i].Status, new SelectList(Model.OrderStatuses, "Id", "StatusName"))
                        </td>
                    </tr>
                }
            </tbody>
        </table>

        <div class="panel-body form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Update" class="btn btn-success" />
            </div>
        </div>
    }
</div>

控制器方法应如下所示:

[HttpPost]
public async Task<ActionResult> AdminOrders(AdminOrdersViewModel model)
{
    // do stuff
}

假设您的Status模型类似于:

public class Status
{
    public int Id { get; set; }
    public string StatusName { get; set; }
}

您可以从上面的列表中创建下拉列表:

@Html.DropDownListFor(m => Model.OrdersDespatched[i].Status, new SelectList(Model.OrderStatuses, "Id", "StatusName"))

PS:还要确保在Get方法中指定状态列表。

好的,我看到你在做什么......

出于某种原因,在asp.net中,MVC似乎应该可行:

@using (Html.BeginForm("AdminOrders", "Manage", new { model = Model }, FormMethod.Post, new
{
    enctype = "multipart/form-data"
}))
{
//Form contents
}

我正在通过模型吗? 好吧,我猜不是,因为它不起作用。

你需要做的是这样的事情(在表单中添加两个隐藏的字段):

@using (Html.BeginForm("AdminOrders", "Manage", new { model = Model }, FormMethod.Post, new
{
    enctype = "multipart/form-data"
}))
{
    @Html.HiddenFor(x => x.OrdersInProgress)
    @Html.HiddenFor(x => x.OrdersDespatched)
}

然后将其设置为在控制器操作中获取两个列表。

尝试将复杂对象(pocos或其他)传递给控制器​​时,我遇到了这个问题,发现必须完全按照命名包含对象,并且必须与控制器所期望的完全匹配。 因此,如果您有一个名为OrdersInProgressList<Order>那么您必须将具有该确切名称的该类型的列表传递给控制器​​,该控制器接受具有该确切名称的该类型的列表。 表单内隐藏的控件应该使用该名称传递该列表。 如果该列表变为空,请检查其名称是否正确。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM