Home > front end >  Use two view models in one view in ASP.NET Core MVC
Use two view models in one view in ASP.NET Core MVC

Time:03-09

I want to create a page that has 2 forms, like page that have both of sign up and sign in forms. But in ASP.NET Core, I can just have one model for one form. I searched for that and I understood I can use view data or view bag for making view model for both of sign in and sign up model but I doubt that this way is correct.

Is it correct?

is it correct???

Then I get a warning

Converting null literal or possible null value to non-nullable type

How can I fix it?

CodePudding user response:

Ideally, you should have different pages for sign in and sign up, you can see some examples here, and I'd definitely recommend you to do some more research before implementing your changes as you have described, but if you still want to go for that option, than one way could be to create one view model that will have both sign in and sign up properties. Rather than using ViewData or ViewBag, you should directly use your view model to populate your view data.

// Example get action result
[HttpGet] 
public IActionResult Login(string returnUrl = "") { 
   var model = new LoginViewModel { ReturnUrl = returnUrl }; 
   return View(model); 
}

// Example post action result
[HttpPost] 
public async Task<IActionResult> Login(LoginViewModel model) { 
   if (ModelState.IsValid) { 
      var result = await _signManager.PasswordSignInAsync(model.Username,
         model.Password, model.RememberMe,false); 
      
      if (result.Succeeded) { 
         if (!string.IsNullOrEmpty(model.ReturnUrl) && Url.IsLocalUrl(model.ReturnUrl)) {
            return Redirect(model.ReturnUrl);
         } else { 
            return RedirectToAction("Index", "Home"); 
         } 
      } 
   } 
   ModelState.AddModelError("","Invalid login attempt"); 
   return View(model); 
}

// Example view
@model LoginViewModel 
@{ 
   ViewBag.Title = "Login"; 
}  
<h2>Login</h2>  

<form method = "post" asp-controller = "Account" asp-action = "Login" 
   asp-route-returnurl = "@Model.ReturnUrl"> 
      <div asp-validation-summary = "ValidationSummary.ModelOnly"></div> 
      
      <div> 
         <label asp-for = "Username"></label> 
         <input asp-for = "Username" /> 
         <span asp-validation-for = "Username"></span> 
      </div> 
      
      <div> 
         <label asp-for = "Password"></label> 
         <input asp-for = "Password" />
         <span asp-validation-for = "Password"></span> 
      </div> 
    
      <div> 
         <label asp-for = "RememberMe"></label> 
         <input asp-for = "RememberMe" /> 
         <span asp-validation-for = "RememberMe"></span> 
      </div> 
   <input type = "submit" value = "Login" /> 
</form>      

CodePudding user response:

You can have one model for the view. You can compose that model with two complex object that represent each form.

  • PageModel
    • SignInModel
    • SignUpModel

You can have two partial views SignIn and SignUp. Then compose a Parent Page with both partial views. The Parent will still have one view model like above, but you can scope the partial views to the root of their models (SignInModel, SignUpModel) instead of nested from the Parent (SignInModel.Username)

  • Related