我的登录和注册表单位于同一页面中,它们由制表符元素分隔。
每个表单都有一个ViewModel:
public class RegisterViewModel
{
public string FullName { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string ConfirmPassword { get; set; }
}
public class LoginViewModel
{
public string Email { get; set; }
public string Password { get; set; }
}
由于两个表单都在同一页面上,因此我有一个父ViewModel:
public class LoginAndRegisterViewModel
{
public LoginViewModel LoginViewModel{ get; set; }
public RegisterViewModel RegisterViewModel{ get; set; }
}
// Actions...
public ActionResult Register()
{
return View("Login");
}
public async Task<ActionResult> Register(LoginAndRegisterViewModel model)
{
// blah.. do stuff here...
return View("Login", model);
}
但是在主视图中,当我尝试使用表单呈现部分时,我在Model.LoginViewModel和Model.RegisterViewModel中得到System.NullReferenceException(附加信息:对象引用未设置为对象的实例。)。这是观点:
Login.cshtml :
@model Models.LoginAndRegisterViewModel
...
@Html.Partial("_LoginPartial", Model.LoginViewModel)
...
@Html.Partial("_RegisterPartial", Model.RegisterViewModel)
我已经看到,通常的做法是遵循这种惯例,详见here in this SO question。我甚至尝试使用this PartialOrNull helper,但我仍然得到例外。我也尝试了基于此的解决方案&#34; Forms for Deep View Model graphs&#34;制品
这也没有用:
@Html.Partial("_LoginPartial", Model.LoginViewModel, new ViewDataDictionary(ViewData){Model = null});
我如何才能拥有这样的注册/登录表?正如我所说的那样,其他SO问题的情况完全相同,并且每个人都报告说该解决方案有效,但那是针对MVC3的
编辑1:添加_LoginPartial作为参考。
@model Models.LoginViewModel
@{
using (Html.BeginForm("Login", "Account", new {ReturnUrl = ViewBag.ReturnUrl}, FormMethod.Post))
{
@Html.TextBoxFor(m => m.Email)
@Html.PasswordFor(m => m.Password)
}
}
编辑2:尝试了?运算符并仍然获得异常。
@Html.Partial("_LoginPartial", Model.LoginViewModel ?? new LoginViewModel())
更新:根据接受的答案,我做了一些测试,现在它没有初始化ViewModel构造函数,也没有在Get操作中发送空的ViewModel。
唯一需要的是将部分视图声明为主模型为@model:
@model Models.LoginAndRegisterViewModel
然后访问部分中的嵌套ViewModel:
@model Models.LoginAndRegisterViewModel
@{
using (Html.BeginForm("Login", "Account", new {ReturnUrl = ViewBag.ReturnUrl}, FormMethod.Post))
{
@Html.TextBoxFor(m => m.LoginViewModel.Email)
@Html.PasswordFor(m => m.LoginViewModel.Password)
}
}
答案 0 :(得分:2)
您应该在视图模型构造函数
中初始化属性LoginViewModel
和RegisterViewModel
public class LoginAndRegisterViewModel
{
public LoginAndRegisterViewModel()
{
LoginViewModel = new LoginViewModel();
RegisterViewModel = new RegisterViewModel ();
}
public LoginViewModel LoginViewModel{ get; set; }
public RegisterViewModel RegisterViewModel{ get; set; }
}
并在GET方法中传递视图模型的新实例
public ActionResult Register()
{
var model = new LoginAndRegisterViewModel();
return View("Login", model);
}
并确保您回溯模型属性,将模型传递给partials
@Html.Partial("_LoginPartial", Model)
并将部分更改为使用LoginAndRegisterViewModel
@model Models.LoginAndRegisterViewModel
@using (Html.BeginForm("Login", "Account", new {ReturnUrl = ViewBag.ReturnUrl}, FormMethod.Post))
{
@Html.TextBoxFor(m => m.LoginViewModel.Email)
@Html.PasswordFor(m => m.LoginViewModel.Password)
}
这可确保控件绑定到视图模型并生成正确的名称属性
<input type="text: name="LoginViewModel.Email"..>
而传递模型的属性会生成
<input type="text: name="Email"..>
在回发后不会绑定到LoginAndRegisterViewModel
,所有属性都为null