Reputation: 108
The scenario:
I'm creating a login form for an MVC2 application.
How i'm doing it:
The form submits to an MVC2 action which validates the username/password. If it fails validation the action returns the form (a partial view) for the user to try again. If it passes validation the action returns the page the user was visiting before they logged in (a view).
What i want to happen:
1 - when the form is submitted and the user validates successfully, The returned result should replace the current page (like what happens if you don't set an UpdateTargetId).
2 - When the form is submitted and the user fails validation, the returned result should replace the form (like what happens if you set the UpdateTargetID to the form's containing element).
The problem:
I can make both of those things work, but not at the same time. I can either have it always replace the current page, or always just replace the contents of the UpdateTargetId element. But I need it to be able to do either depending on whether the user successfully validated or not.
What I need
The ideal solution would be to be able to examine the result of the ajax request and determine whether to use the UpdateTargetId (replacing just the form) or not (replacing the whole page). I expect it would involve some work with jquery (assuming it's possible) but i'm not really that great with jquery yet to figure out how to do it myself. If it can't be done this way I'm also open to other methods/solutions for making it work in a similar fashion.
Thanks in advance ..
As requested. Code for the action. But as i said. It's the standard LogOn action that ships default with every mvc application. The only difference is it returns a partial view when validation fails.
[HttpPost]
[MedLife.Code.Compression.CompressFilter]
public ActionResult SignIn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (MembershipService.ValidateUser(model.UserName, model.Password))
{
FormsService.SignIn(model.UserName, model.RememberMe);
if (!String.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return PartialView("Overlays/LoginControl", model);
}
Upvotes: 1
Views: 950
Reputation: 13581
In your server side code, check to see if the validation works, if not, return a RedirectToAction to whatever full view you need.
The issue you have is all application logic, as opposed to display logic, so it should be done in the Controller rather than the view to keep your concerns separate.
You have to do a RedirectToAction (ie, not just return View("myViewWhenInvalid");) because otherwise the view will be rendered in the UpdateTargetID, which won't look good.
EDIT:
Ie:
public ActionResult myLoginAction(string name, string pwd)
{
// do the login stuff
if (loggedIn)
{
return RedirectToAction(...);
}
else
{
return MyJsonAction();
}
}
public MyJsonAction()
{
return some Json...;
}
PS: I have a cold, so disinclined to check my idea.
Upvotes: 1
Reputation: 4698
Let's assume you return a Json result with the string "INVALID" if the login/password is invalid. Then you use the UpdateTargetId.
If the Json result != "INVALID" then you would replace the container with new partial page.
That's how I do it and it works great. :-)
Upvotes: 1