Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 尝试将嵌套的ViewModel传递给分部时出现NullReferenceException_C#_Asp.net Mvc_Razor_Asp.net Mvc 5 - Fatal编程技术网

C# 尝试将嵌套的ViewModel传递给分部时出现NullReferenceException

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; }

我的登录表单和注册表单位于同一页面中,它们由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 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