我正在使用一个viewmodel,它包含每个局部视图的一些其他模型(实体)。 我通过传递ViewModel中的实体来渲染局部视图。我的局部视图有几个字段和一些按钮。单击按钮(在我的局部视图中),表单将被回发,数据在子实体中,而我的viewmodel总是以null返回... 我需要在回发后的viewmodel中显示数据。
所有观点都是强类型的:
代码:
public class OrdersVM
{
public FiltersVM filterCriteria { get; set; }
public IEnumerable<MeterInventory> meters { get; set; }
public string assignTo { get; set; }
public IEnumerable<SelectListItem> AssigneeOptions { get; set; }
}
public partial class Meters
{
public int MTRNO { get; set; }
public string LOCName { get; set; }
}
public class FiltersVM
{
public string Center { get; set; }
public DateTime? DueDate { get; set; }
}
查看代码
@model OrdersVM
@{
ViewBag.Title = "Orders";
}
@using (Html.BeginForm())
{
<div>
@Html.Partial("~/Views/Base/Filters.cshtml", Model.filterCriteria)
</div>
@foreach (var item in Model.meters)
{
<table>
<tr>
<td>
@Html.Encode(item.LOCNAME)
</td>
</tr>
</table>
}
}
控制器代码
[HttpPost]
public ActionResult Index(OrdersVM orders, FiltersVM filters)
{
//orders is null
//filters has values
}
谢谢Olivehour。我正在使用局部视图“Filters.cshtml”。并且呈现相同的。
以下是部分视图的代码:
@model ViewModels.FiltersVM <fieldset>
<legend>Order Assignment</legend>
<table id="tbl1" class="tableforcontrols">
<tr>
<td>
<div class="editor-label">
@Html.LabelFor(model => model.LDC)
</div>
</td>
<td>
<div class="editor-field">
<input type="submit" value="Search" id="btnSearch" name="button" />
</div>
</td>
<td>
<div class="editor-field">
<input type="submit" class="cancel" value="Reset" id="btnReset" name="button" />
</div>
</td>
</tr>
</table> </fieldset>
我尝试使用单个参数“OrdersVM”(父视图模型),但没有运气。
[HttpPost]
public ActionResult Index(OrdersVM orders)
但如果我将父视图模型传递给局部视图,它将数据保存在OrdersVM.filterCriteria中,但不包含属性(IEnumerable米,字符串assignTo和Enumerable AssigneeOptions)
@Html.Partial("~/Views/Base/Filters.cshtml", Model)
我是MVC的新手。如果有人找到解决方案,请告诉我。
提前致谢。
答案 0 :(得分:0)
看起来你在这里有几个问题。在您的操作方法中,订单arg为null的一个可能原因是因为它看起来不像是在渲染任何输入元素。你只有@Html.Encode(item.LOCNAME)
。
为了使默认模型绑定器构造OrdersVM
的实例并将其传递给action方法,它需要从HTTP POST输入。您需要更像@Html.TextBoxFor(m => item.LOCNAME)
的内容。
我认为第二个问题是你在action方法中有2个参数。由于OrdersVM
已经具有FiltersVM
属性,因此您应该能够为action方法设置一个OrdersVM
参数。在HTTP POST期间,您只需从FiltersVM
访问OrdersVM.filterCriteria
个属性即可。不过,这将导致您的第三次挑战,因为meters
上的OrdersVM
属性是IEnumerable
集合。
要解决这个问题,首先要读几this article about model binding collections次。它已经过时了,但它仍适用于MVC3。阅读它,并真正包围它。
如果您不喜欢使用整数来索引集合字段,那么有一个HTML helper written by Steve Sanderson允许您使用GUID索引集合输入。我们一直使用它,但它可能很棘手 - 主要是,您应该始终将集合项放在局部视图中。现在,您可能最好使用Haacked文章中概述的基于整数的索引。
答案 1 :(得分:0)
听起来你是来自Webforms。要转换到MVC,您需要删除PostBack的想法。这个概念在网络上并不存在,但Webforms为我们伪造了它。
在MVC中,您通常以/ edit / {someId}之类的GET请求开始。从这里,您可以从数据库加载viewmodel的数据并渲染视图。现在让我们说viewmodel中的所有数据都是可编辑的,因此每个属性都有自己的输入字段。用户编辑一些数据并保存表单。这会向服务器发出POST。
假设我们有这个POST方法
[HttpPost]
public ActionResult Edit(MyViewModel model)
在这种情况下,您需要模型化所需的所有数据,因为表格中存在所有数据。
您可以执行此操作并获取相同的视图,因为所有数据都是数据绑定的。
[HttpPost]
public ActionResult Edit(MyViewModel model){
return View(model);
}
现在让我们假装你的表格中有一个下拉列表。然后,您将在viewmodel中拥有这两个属性。
public int CarId { get; set; }
public IEnumerable<SelectListItem> CarOptions {get; set; }
这次发布表单时,CarId将填充在ViewModel中,但不会填充CarOptions,因为它们不是表单数据的一部分。如果你想再次返回相同的视图,你所做的就是重新加载缺失的部分。
[HttpPost]
public ActionResult Edit(MyViewModel model){
model.CarOptions = LoadCarOptions();
return View(model);
}
如果你把它放在一个隐藏的领域,那当然也可以模拟绑定。但是再次从服务器/数据库重新加载它会更容易,也可能更有效。这是使用MVC时采用的常规方法。