尝试将绑定建模到我的视图模型时遇到一些问题。
因此基本的视图模型是:
public class RegistrationVM
{
public TravelHistoryVM TravelHistory {get;set;}
public UserDetailVM UserDetails {get;set;}
public ICollection<HandsetDevicesVM> ExistingDevices {get;set;}
}
另外3个视图模型的包装器,每个视图模型包含通常的字符串,整数和bool。暂时忽略HandsetDevicesVM的集合。
我有以下观点(为清晰起见,样本)
@using (Html.BeginForm())
{
@Html.ValidationSummary(false)
@Html.LabelFor(model => model.TravelHistory.DoNotTravel)
@Html.CheckBoxFor(model => model.TravelHistory.DoNotTravel)
@Html.EditorFor(model => model.UserDetails, "UserDetailsHidden")
}
“TravelHistory”对象被绑定正常,没有问题。 回传数据时,'UserDetails'对象始终为null。
模板肯定是渲染,我可以从HTML中看出来。模板本身如下:
@model Foo.Bar.UserDetailVM
@Html.HiddenFor(model => model.EmailAddress)
@Html.HiddenFor(model => model.FirstName)
@Html.HiddenFor(model => model.Surname)
@* etc etc *@
生成的HTML是
<input data-val="true" data-val-required="The Email Address field is required." id="UserDetails_EmailAddress" name="UserDetails.EmailAddress" type="hidden" value="stack@overflow.com" />
<input data-val="true" data-val-required="The First Name field is required." id="UserDetails_FirstName" name="UserDetails.FirstName" type="hidden" value="Stack" />
<input data-val="true" data-val-required="The Surname field is required." id="UserDetails_Surname" name="UserDetails.Surname" type="hidden" value="Overflow" />
我在另一个视图上使用此EditorTemplate没有问题(它绑定到该视图模型没问题)。
最后,使用Fiddler我可以确定信息正在发布..我想
UserDetails.EmailAddress=stack%40overflow.com.test&UserDetails.FirstName=stack&UserDetails.Surname=overflow
有什么想法吗?我应该在哪里集中精力进行调试?
Edit1:刚刚从ModelState对象中注意到了这一点
AttemptedValue: 'Foo.Bar.UserDetailVM'
所以它似乎试图将字符串值'Foo.Bar.UserDetailVM'绑定到对象并且(显然)失败。
EDIT2:
[HttpPost]
public ActionResult Travel(RegistrationVM model)
根据要求,我正在发布的行动
EDIT3:
啊......好的回到舞台,这是提供视图的动作方法
[HttpGet]
public ActionResult Travel(PreRegistrationVM model)
{
if (TempData["PreRegistrationVM"] != null)
{
model = (PreRegistrationVM)TempData["PreRegistrationVM"];
}
var newModel = new RegistrationVM(model);
return View(newModel);
}
这就是我一直在使用的(因此已经成为不起作用的过程的一部分)。基本上,先前步骤中的信息保存在TempData中,并在此方法中选取。然后,它用于如上所述实例化VM。此时(如果我在此处插入断点),模型将填充我期望的数据。
如果我将其修改为以下内容:
[HttpGet]
public ActionResult Travel(PreRegistrationVM model)
{
var newModel = new RegistrationVM
{
FirstName = "Stack",
Surname = "Overflow"
};
return View(newModel);
}
它按预期结合。 TempData是罪魁祸首吗?
答案 0 :(得分:0)
快速背景调查:这是在创建“向导”逐步注册过程时遇到的问题。我想避免在注册完成之前将信息保存到数据库。因此,我们的想法是使用TempData集合在Actions之间存储信息,并使用RedirectToAction从一步到另一步。
对于它的价值,我修改了使用TempData的方法,如此
[HttpGet]
public ActionResult Travel(PreRegistrationVM model)
{
if (TempData["PreRegistrationVM"] != null)
{
model = (PreRegistrationVM)TempData["PreRegistrationVM"];
}
var newModel = new RegistrationVM(model);
return View(newModel);
}
在注册过程中的每一步检索数据库中的信息。
[HttpGet]
public ActionResult Travel(int id)
{
var model = FooRepository.GetById(id);
return View(model);
}
我不完全确定为什么TempData方法导致了这一点,我会对那些比我提供理由更多学习的人感兴趣。
感谢所有回答的人,帮助我追踪它。