C# 尝试将嵌套的ViewModel传递给分部时出现NullReferenceException
我的登录表单和注册表单位于同一页面中,它们由tab元素分隔 每个表单都有一个ViewModel:C# 尝试将嵌套的ViewModel传递给分部时出现NullReferenceException,c#,asp.net-mvc,razor,asp.net-mvc-5,C#,Asp.net Mvc,Razor,Asp.net Mvc 5,我的登录表单和注册表单位于同一页面中,它们由tab元素分隔 每个表单都有一个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 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; }
}
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);
}
由于两个表单位于同一页面上,我有一个父视图模型:
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; }
}
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);
}
我已经看到,遵循这种惯例是一种常见的做法,详细说明如下。我甚至试过使用,但还是有例外。我还尝试了基于这篇“”文章的解决方案
这也不起作用:
@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)
}
}
您应该在视图模型构造函数中初始化属性
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"..>
它不会在回发时绑定到
LoginAndRegisterViewModel
,并且所有属性都将为null,但仍然会得到异常。我编辑了问题并添加了_LoginPartial,以防我在那里做错了什么。问题是,如果我将表单放在Login中,没有部分,一切都会正常工作:@Html.PasswordFor(m=>m.LoginViewModel.Password)。但是我预计会有更复杂的表单,所以我需要让这些部分工作。你的部分看起来很好,你已经正确地声明了你的模型。但是,即使这样做有效,您也无法回发到Register
,因为控件的命名不正确。例如,它需要是
,但因为您只将一个属性传递给partial,所以它将呈现
,因此它不会绑定。您需要将部分更改为@model.LoginAndRegisterViewModel
,并将部分呈现为@Html.Partial(“\u LoginPartial”,model)
,谢谢!将partials更改为父视图模型,然后在partials中包含@Html.TextBoxFor(Model=>Model.LoginViewModel.Email)。我再也没有例外了。(1) 我找到的所有与MVC3和MVC4相关的解决方案看起来都像是MVC5,我们需要始终将父视图模型发送到partials?甚至扩展助手也不能像PartialOrNull那样工作。(2) 既然正确答案在评论中,我还能接受你的答案吗?或者我该怎么办?如果你编辑你的答案,然后我可以接受它呢?嗨,如果你在ViewModles中有3层嵌套,这仍然有效吗?e、 g ViewModelA->ViewModelB->ViewModelC,其中->表示“包含”,或者您可以查看嵌套模型的方式是否有限制?我有问题,我有3个视图模型嵌套如上,我失去了从最内部的视图模型回发的数据。我将Partent视图模型传递给partial,并在partial im中引用类似model.ViewmodelB.viewmodelC.Property的viewmodelC