tags:

views:

35

answers:

1

I'm using MVC. I copied the login form from the login page and inserted into a new page (home controller, index view). I copied the code from the accounts controller into the index view. for some reason, i'm still not able to login. I'm not sure what's wrong as it looks like I copied the necessary code exactly. When I use the form on the index page, I don't get any validation errors, but it returns me back to the view and I'm not logged in.

You'll notice that I changed this line to redirect to an Error page but I never get this far:

// If we got this far, something failed, redisplay form
            return RedirectToAction("Error", "Home");

I posted the code here: http://pastebin.com/RUj6ASvE

+1  A: 

It's because you are posting the from to the Index action whereas you should be posting it to the LogOn action, where your authentication logic is in.

Try changing Html.BeginForm() to Html.BeginForm("LogOn", "HomeController") in your view.

In the code you posted you were presenting the form from the HomeController's Index action. And posting it back to the same controller's same action. But that action was not handling the authentication logic. That's why nothing was happening and you weren't logging in.

In the default ASP.NET MVC 2 site, however, they are presenting the form from the AccountController's LogOn action :

public ActionResult LogOn() {
    return View(); //returns the LogOn.aspx view
}

So when they use Html.BeginForm() in the view, it creates a form that will POST to the same controller's same action. So they create another action with the name LogOn :

[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl) {
    //...
}

But this time they decorate that action with the HttpPost attribute. That means if a request hits the AccountController's LogOn action with the POST verb, that method above will be executed. But if the same action is requested with the GET verb (ie without a POST body) the other method will be executed.

So basically, you could have done this in your HomeController :

public ActionResult Index() {
    ViewData["Message"] = "Welcome to ASP.NET MVC!";
    return View(); //returns the view which has the form
}

[HttpPost]
public ActionResult Index(LogOnModel model, string returnUrl) {
    //handles the post
}

But your action (the one that was supposed to handle the authentication logic) was named differently. And that's why we needed to explicitly set the controller and the action name in the Html.BeginForm("LogOn", "HomeController").

çağdaş
that was it! Can you tell me why in the LogOn form view it didn't have to be that way, though? Here's the code from the standard asp.net mvc login controller and view that i copied from: http://pastebin.com/xkLuazSi
Jason Shultz
@Jason Shultz, When you define a form with `Html.BeginForm()` it sets the form's action attribute to the current route. So the LogOn view did not need to explicitly set the controller and action because it needed to post the form to the same controller and the same **action** but with POST method. I hope that makes sense.
çağdaş
I understand what your saying, I'm just having a difficulty seeing the difference between /home/index and /accounts/logon. to my untrained eye I don't see the difference.
Jason Shultz
@Jason Shultz, I edited the answer to explain in detail. I hope it helps.
çağdaş
thank you! That was great. I didn't notice I had renamed(kept?) my post action to Logon the same when I copied it from the accounts controller. At night, under the gun, you don't notice the simple things until it's too late. You taught me a valuable lesson, thanks!
Jason Shultz
Glad to hear it was helpful :)
çağdaş