2012-04-18 73 views
2

有一些问题试图建模绑定到我的视图模型。MVC3模型绑定问题与EditorTemplates

基本视图模型是这样的:

public class RegistrationVM 
{ 
    public TravelHistoryVM TravelHistory {get;set;} 
    public UserDetailVM UserDetails {get;set;} 
    public ICollection<HandsetDevicesVM> ExistingDevices {get;set;} 
} 

一种用于图3周进一步的ViewModels包装,每个包含的字符串,整数和布尔变量通常的频带。暂时忽略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数据回传时,UserDetails对象始终为空。

模板绝对是渲染,我可以从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="[email protected]" /> 
<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。

最后,使用招我能够确定该信息被张贴..我认为

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:

唉唉.. OK回到舞台,这是提供了操作方法的查看

[HttpGet] 
public ActionResult Travel(PreRegistrationVM model) 
{ 
    if (TempData["PreRegistrationVM"] != null) 
    { 
     model = (PreRegistrationVM)TempData["PreRegistrationVM"]; 
    } 
    var newModel = new RegistrationVM(model); 
    return View(newModel); 
} 

这就是我一直在使用的(因此一直是过程的一部分t不起作用)。基本上来自前一步骤的信息保存在TempData中并以此方法提取。然后它被用来像上面那样实例化VM。此时(如果我在此处插入断点),模型将按照我的预期填充数据。

如果我修改那个以下:

[HttpGet] 
public ActionResult Travel(PreRegistrationVM model) 
{ 
    var newModel = new RegistrationVM 
    { 
     FirstName = "Stack", 
     Surname = "Overflow" 
    }; 
    return View(newModel); 
} 

它结合预期。 TempData是这里的罪魁祸首吗?

+0

您能否显示您发布此表单的行为的确切签名? – 2012-04-18 15:09:17

+0

1 - 我假设你正在发回'RegistrationVM'? 2 - 另外,为什么当用户没有任何要编辑的东西时,你使用EditorTemplate? DisplayTemplate将是更合适的选择。 3 - 如果你的操作方法是一个'UserDetailsVM'的另一个参数,它是否正确绑定?我想你会需要你的'yourVariable.UserDetails.EmailAddress'来正确绑定。 – Tejs 2012-04-18 15:09:50

+0

我怀疑问题在于你没有发布的东西。我没有看到你在做什么错。 – 2012-04-18 15:10:21

回答

0

快速背景检查:这是在创建“向导”逐步注册过程时遇到的问题。我想避免将信息保存到数据库,直到注册完成。因此,这个想法是使用TempData集合在Actions之间存储信息,并使用RedirectToAction逐步移动。

对于什么是值得的,我使用像这样

[HttpGet] 
public ActionResult Travel(PreRegistrationVM model) 
{ 
    if (TempData["PreRegistrationVM"] != null) 
    { 
     model = (PreRegistrationVM)TempData["PreRegistrationVM"]; 
    } 
    var newModel = new RegistrationVM(model); 
    return View(newModel); 
} 

TempData的检索每在登记过程中的步骤,一旦数据库中的信息修改的方法。

[HttpGet] 
public ActionResult Travel(int id) 
{ 
    var model = FooRepository.GetById(id); 
    return View(model); 
} 

我不完全确定为什么TempData方法导致这种情况,会对比我提供理由的人更感兴趣。

非常感谢所有回答,帮我追踪下来。