[英]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 table
和Orders 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或其他)传递给控制器时,我遇到了这个问题,发现必须完全按照命名包含对象,并且必须与控制器所期望的完全匹配。 因此,如果您有一个名为OrdersInProgress
的List<Order>
那么您必须将具有该确切名称的该类型的列表传递给控制器,该控制器接受具有该确切名称的该类型的列表。 表单内隐藏的控件应该使用该名称传递该列表。 如果该列表变为空,请检查其名称是否正确。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.