I create a single page to manage login and registration task in my mvc 4 app. when i create a user using registration, and registration fails - eg password mismatch - the page process the error and refresh but inserting a complete page in the renderaction part of register.
on the other hand, when login fail - user not exists - the page refresh but direct the user to a page displaying only the renderaction login part, not the whole layout.. any help appreciated:
steps: I created a model
public class Access
{
public LoginModel LoginModel { get; set; }
public RegisterModel RegisterModel { get; set; }
}
then I create a page:
<div class="main-content" style="min-height: 700px;">
<!-- Login form -->
@{ Html.RenderAction("Login", "Account"); }
<!-- Register form -->
@{ Html.RenderAction("Register", "Account"); }
<div class="clear"></div>
</div>
the controller is the typical one provided in mvc4 template. an example for login
public ActionResult Login(LoginModel model, string returnUrl)
{
if (ModelState.IsValid && WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
{
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
// If we got this far, something failed, redisplay form
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return PartialView(model);
}
You're returning a ParitalView on fail, you may want to return the view that contains the whole page. ie edit
//recreate the compound viewmodel in the login controller
Access viewModel = new Access();
viewModel.LoginModel = model;
viewModel.RegisterModel = new RegisterModel();
return View("LoginOrRegister", viewModel); //supposing the view name is LoginOrRegister.cshtml
//recreate the compound viewmodel in the register controller
Access viewModel = new Access();
viewModel.LoginModel = new LoginModel();
viewModel.RegisterModel = model;
return View("LoginOrRegister", viewModel); //supposing the view name is LoginOrRegister.cshtml
also the loginorregister.cshtml page will have to use the Access class that encompasses both the LoginModel and RegisterModel as the model for the View, ie. @model Access
And when you render the login or register model, you need to pass in the model parameters - so that the user doesn't need to re-enter data. *edit - Also try changing from RenderAction to Html.RenderPartial() so that it doesn't route through the actions for the intial render - do this and add [HttpPost] annotations on the controllers * the code would look something like
@model Access
<div class="main-content" style="min-height: 700px;">
<!-- Login form -->
@{ Html.RenderPartial("Login", new {model = Model.LoginModel, returnUrl = "?"}) };
<!-- Register form -->
@{ Html.RenderPartial("Login", "Account", new { model = Model.RegisterModel) }; }
<div class="clear"></div>
</div>
and
[HttpPost]
public ActionResult Login(LoginModel model, string returnUrl)
{
if (ModelState.IsValid && WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
{
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
// If we got this far, something failed, redisplay form
ModelState.AddModelError("", "The user name or password provided is incorrect.");
//recreate the compound viewmodel in the login controller
Access viewModel = new Access();
viewModel.LoginModel = model;
viewModel.RegisterModel = new RegisterModel();
return View("LoginOrRegister", viewModel);
}
ah, also instead of using the viewbag to initially pass in the data, you'd have to pass it in using the model - because I've elected to use the code "@Model Acesss" in the razor view, so the register ActionResult would look like...
public ActionResult Register(){
Access viewModel = new Access();
viewModel.LoginModel = new LoginModel();
viewModel.RegisterModel = new RegisterModel();
return View("LoginOrRegister",viewModel);
}
I didn't realize you were so new to mvc. Keep at it. :) Another tutorial may help