views:

78

answers:

3

This is probably again a newbie question.

When I create an ASP.NET MVC2 application, an Account Controller with an Action LogIn is created like this:

[HttpPost]
public ActionResult LogOn(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 View(model);
    }

Now, I don't want to have a login page, I want to have login controls as part of a bigger page. So, I changed Login.aspx to Login.ascx and I am integrating it in my main view either with Html.RenderPartial or Html.RenderAction.

Both works like a charm if the login is successfull. If it is not, the

return View(model)

is killing me. What I want is to go back to my main page (call it Home/Index) but with the error information of the partial view.

return RedirectToAction("Index", "Home")

Obviously doesn't work.

Hints?

+1  A: 

Yeah redirecttoaction but provide an error message with it in the tempdata so you should do something like this

TempData["errorMsg"] = "incorrect values provided";
return RedirectToAction("Index", "Home")

Of course in the main index you should have a div that displays the message

<%= html.Encode(TempData["errorMsg"]) %>

EDIT I see you want to maintain the modelstate that might be a problem but what you could do is pass the modelstate in the index action or pass the modelstate object in the tempdata. What you can do then is check if a there are modelstate errors in the object and if there are check the field and add the error to the right field.

Chino
Hm, probably I could put the whole LogOnModel in the TempData. But to me this seems to be a hack. What would be the clean solution here?
Sparhawk
Yes it is a hack the clean solution is to write a filter for it. Look at this question and my answer for an examplehttp://stackoverflow.com/questions/2503032/where-to-use-controller-httpcontext/2503085#2503085In the filter you check if the modelstate is valid if not re add the values of course it would be better to put this in a custom attribute because I do not think you need this in all actions of a controller. You can then use the attribute on actions in which you want to maintain the modelstate.
Chino
Meh. This is what TempData is for. My guess is you don't like the magic strings and lack of strongly typed data. That's fair, but its a style choice, not a hack.
AndrewDotHay
A: 

You could explicitly specify the view to return:

return View("~/Views/Home/Index.aspx", model);

This way error information will be preserved and correct view rendered.

Darin Dimitrov
If I did this, I would pass the LogOnModel to the Home/Index-View. That probably wouldn't work. Perhaps the question is not so newbie after all :)
Sparhawk
@Sparhawk, you are correct. What if you returned the model of the Home/Index view? The LogOn view model should be a subset of the Home/Index view model. As an alternative you could ajaxify the LogOn form and invoke this action asynchronously which in case of success the redirect would be performed on the client (window.location.href) and in case of error it would return a `PartialView` and the script calling this action would refresh the `div` containing this form.
Darin Dimitrov
Currently it is not a subset of the Home/Index view model. I have a portal and each page (like Home/Index) has a number of controls on it. I am rendering the controls with RenderAction into the page. So, why should the Home/Index view now anything about a LogonModel?Sure, I could use ajax. But that would feel like circumventing the issue. Is there no clean solution for partial views with validation logic?
Sparhawk
A: 

Take a look at practice #13 on this blog. This method works well to pass modelstate information when you're coding in the PRG (Post-Redirect-Get) style. You'll just need to create a couple of action filters and apply them to your get and post actions as appropriate.

Tahbaza