好的,所以有很多关于此的问题,但我似乎无法让这个工作。它应该很简单,但我还是摸不着头脑。
控制器:
[HttpPost]
public ActionResult Edit(BookingIndexViewModel vm) // Also tried BookingViewModel
{
return View();
}
容器视图模型:
public class BookingIndexViewModel
{
public int id { get; set; }
public List<BookingViewModel> bookings { get; set; }
public List<SelectListItem> allAttendances { get; set; }
}
预订视图模型(我真正感兴趣的VM)
public class BookingViewModel
{
public int id { get; set; }
public int referralId { get; set; }
public int attendanceId { get; set; }
}
视图
@model Project.ViewModels.BookingIndexViewModel
@using Project.ViewModels
<fieldset>
<legend>Registered patients</legend>
@if (Model.bookings.Count < 1)
{
<div>None currently registered</div>
}
else
{
<table>
<tr>
<th>
<span class="display-label">@Html.LabelFor(model => model.bookings[0].forenames)</span>
</th>
<th>
<span class="display-label">@Html.LabelFor(model => model.bookings[0].surname)</span>
</th>
<th>
<span class="display-label">@Html.LabelFor(model => model.bookings[0].dob)</span>
</th>
<th>
<span class="display-label">@Html.LabelFor(model => model.bookings[0].attendance</span>
</th>
</tr>
@{
foreach (BookingViewModel b in Model.bookings)
{
using (Html.BeginForm("Edit", "Booking"))
{
@Html.HiddenFor(x => x.id)
<tr>
<td>
<span class="display-field">@b.forenames</span>
</td>
<td>
<span class="display-field">@b.surname</span>
</td>
<td>
<span class="display-field">@String.Format("{0:dd/MM/yyyy}", b.dob)</span>
</td>
<td>
@Html.DropDownListFor(model => b.attendanceStatusId, Model.allAttendances)
</td>
<td>
<input type="submit" value="Save" />
</td>
</tr>
}
}
}
</table>
}
</fieldset>
因此视图接受容器视图模型BookingIndexViewModel
并为所持有的每个BookingViewModel
创建一个表单。提交时,我希望它使用修改后的BookingViewModel
传回容器视图模型,但它始终为空。我也尝试过期望使用相同结果修改的单BookingViewModel
。 MVC是否提交了与视图中给出的类型相同类型的水合视图模型或从表单块中推断出的类型?
我从视图中检索的唯一重要值是修改后的attendanceId
(应由下拉帮助程序填写)和预订ID。
答案 0 :(得分:3)
问题几乎肯定与你如何渲染这个
有关foreach (BookingViewModel b in Model.bookings)
{
@Html.HiddenFor(x => x.id);
...
@Html.DropDownListFor(model => b.attendanceStatusId, Model.allAttendances)
}
上面的HTML看起来像
<form ... >
<input type="hidden" name="BookingIndexViewModel.id" ... />
<select name="BookingViewModel.attendanceStatusId" ... />
</form>
...
<form ... >
<input type="hidden" name="BookingIndexViewModel.id" ... />
<select name="BookingViewModel.attendanceStatusId" ... />
</form>
...
MVC模型绑定器使用name
字段将数据绑定到目标模型,在您拥有BookingIndexViewModel
的方案中,您应该找到的至少 <{1}}字段已填充,但您的id
肯定是空的。
目前还不完全清楚你要做什么,我怀疑你想要的是显示整个预订信息,但只发布个人List<BookingViewModel>
?如果是这种情况,以下内容应该有效
<强>控制器强>
BookingViewModel
查看强>
[HttpPost]
public ActionResult Edit(BookingViewModel model)
{
...
}
答案 1 :(得分:1)
在我看来 你应该知道asp.mvc中的模型绑定是如何工作的,这里有一个很好的链接,它提供了有关asp.mvc模型绑定的详细信息 http://msdn.microsoft.com/en-us/magazine/hh781022.aspx 虽然文章很长,但它可以帮助你了解模型绑定的工作原理
以及你应该查看你的HTML页面,知道你的html控件是如何命名的 根据您在剃刀页面中查看模型的剃刀助手
答案 2 :(得分:0)
ASP.NET MVC中没有“回发”。它像HTTP一样无状态。 如果要向服务器提交内容,则必须将其包含在表单中。
我认为将视图模型中的整个对象列表传递回服务器并不是一个好主意。
您有Edit
个动作。将其参数类型更改为BookingViewModel
。这将允许您编辑单个预订项目。然后在表单中添加@Html.HiddenFor(x => x.referralId)
之类的内容。
答案 3 :(得分:0)
在查看类似的问题之后,我使用for(){}
尝试而不是foreach(){}
,现在它可以正常工作了。我希望它与每种类型循环中元素的可变性有关。
答案 4 :(得分:0)
MVC实际上并没有特别提交任何内容,也不知道您提交给Action的预期ViewModel
。它不会重新发布您的ViewModel
,就好像它是“viewstate”。
最终它只是在你的html中发布表单中的任何输入元素,并且Action方法在被调用时会尝试从POST中包含的值中提取(使用绑定器)你声明为参数的任何内容。
在您的情况下,您似乎只会提交隐藏的 ID 和 attendanceStatusId 。如果您查看浏览器的实际网络流量,您会注意到正在发布的内容。
因此,您的Action应该期望具有两个与这些输入字段名称匹配的属性的不同ViewModel。