Reputation: 1279
I am trying to learn MVC 3 & Razor and I'm stuck here for 3 hours now. This is what I have
MVC project created using the default template with Account registration and all that good stuff from the template. What I'm trying to do is have both registration page and login page in the index of the HomeController so I created a partial view for both Register (_RegisterPartial) and LogOn (_LogOnPartial). When I go to the index page, I see the registration and login forms which is good but when I try to login or register it goes into an infinite loop.
My HomeController looks like this;
// **************************************
// Registration
// **************************************
public ActionResult DoRegister()
{
return PartialView("_Register");
}
[HttpPost]
public ActionResult DoRegister(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
MembershipCreateStatus createStatus = MembershipService.CreateUser(model.UserName, model.Password, model.Email, model.UserProfile);
if (createStatus == MembershipCreateStatus.Success)
{
FormsService.SignIn(model.UserName, false); // createPersistentCookie
return View("Success");
}
else
{
ModelState.AddModelError("", AccountValidation.ErrorCodeToString(createStatus));
}
}
// If we got this far, something failed, redisplay form
ViewBag.PasswordLength = MembershipService.MinPasswordLength;
return View(model);
}
// **************************************
// Login
// **************************************
public ActionResult DoLogin()
{
return PartialView("_Login");
}
[HttpPost]
public ActionResult DoLogin(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (MembershipService.ValidateUser(model.UserName, model.Password))
{
// logged in
FormsService.SignIn(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl))
{
Redirect(returnUrl);
}
else
{
View("Success");
}
}
else
{
// Not logged in
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View("Success");
}
and my cshtml looks like this;
@{
ViewBag.Title = "Home Page";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@if (Request.IsAuthenticated)
{
@Html.ActionLink("Log Off", "LogOff", "Account")
}
else
{
Html.RenderAction("DoLogin");
Html.RenderAction("DoRegister");
}
Regards,
Ryan
Upvotes: 2
Views: 6266
Reputation: 24847
I can't exactly replicate your situation but I would say that you partial forms are not posting correctly. Have a look a rendered html of the page and check where the forms are being posted to. My guess is that they are being posted to the Index
action. Coupled with the redirect, I think that is where the infinite loop is coming from.
My guess is the html rendered for both forms are similar and posting to the same action i.e. <form action="/" method="post">
, since they are being rendered by the HomeController's Index action.
Change the partial forms (_Login.cshtml
and _Register.cshtml
) and explicitly state which action/controller combination to post to (more on Html.BeginForm from MSDN)
@using (Html.BeginForm("DoLogin","Home")) {/*snipped*/} //in _Login.cshtml
@using (Html.BeginForm("DoRegister","Home")) {/*snipped*/} //in _Register.cshtml
Also I would change the Html.RenderAction
calls to
Html.RenderPartial("_Login");
Html.RenderPartial("_Register");
Upvotes: 1
Reputation: 1038810
Do you read exception messages?
A public action method 'Register' was not found on controller 'AudioRage.Controllers.HomeController'
Now look at the code of HomeController
you've posted. Do you see a Register action on it? I don't.
So add one:
public ActionResult Register()
{
...
}
In your HomeController
you have an action called Register but action is only accessible through POST verbs as it is decorated with the [HttpPost]
attribute:
[HttpPost]
[ActionName("Register")]
public ActionResult Index(RegisterModel model)
so you cannot invoke it with a GET verb on /Home/Register
.
Upvotes: 3