title: MVC4 Register link redirects to login action instead of redirect action
body: <p>I have an MVC4 application that I originally created from the Intranet template, and have modified it to the Internet template, and using the SimpleMembershipProvider.</p>
  
  <p>When I run the app, I get correctly directed to the login view. But if I click Register to add a new user, I am redirected to the login action, not the register action. I put breakpoints in the two Register actions, and they never get hit.</p>
  
  <p>furthermore, when I let fiddler watch what's going on, I see the login action firing multiple times:</p>
  
  <pre><code>#   Result  Protocol    Host    URL Body    Caching Content-Type    Process Comments    Custom  
  2   302 HTTP    localhost:52281 /Security/Register  165 private text/html; charset=utf-8    iexplore:3584           
  3   200 HTTP    localhost:52281 /Security/Login?ReturnUrl=%2fSecurity%2fRegister    4,152   private text/html; charset=utf-8    iexplore:3584           
  4   302 HTTP    localhost:52281 /Content/DashboardSite.css  173 private text/html; charset=utf-8    iexplore:3584           
  5   302 HTTP    localhost:52281 /Scripts/modernizr-2.5.3.js 174 private text/html; charset=utf-8    iexplore:3584           
  6   302 HTTP    localhost:52281 /Images/Site-logo.png   168 private text/html; charset=utf-8    iexplore:3584           
  7   302 HTTP    localhost:52281 /Images/Settings.png    167 private text/html; charset=utf-8    iexplore:3584           
  8   302 HTTP    localhost:52281 /Scripts/jquery-2.0.3.js    171 private text/html; charset=utf-8    iexplore:3584           
  9   302 HTTP    localhost:52281 /Scripts/jquery.unobtrusive-ajax.js 182 private text/html; charset=utf-8    iexplore:3584           
  10  302 HTTP    localhost:52281 /Scripts/jquery.validate.js 174 private text/html; charset=utf-8    iexplore:3584           
  11  302 HTTP    localhost:52281 /Scripts/jquery.validate.unobtrusive.js 186 private text/html; charset=utf-8    iexplore:3584           
  12  200 HTTP    localhost:52281 /Security/Login?ReturnUrl=%2fImages%2fSite-logo.png 4,155   private text/html; charset=utf-8    iexplore:3584           
  13  200 HTTP    localhost:52281 /Security/Login?ReturnUrl=%2fContent%2fDashboardSite.css    4,160   private text/html; charset=utf-8    iexplore:3584
  14  200 HTTP    localhost:52281 /Security/Login?ReturnUrl=%2fScripts%2fjquery-2.0.3.js  4,158   private text/html; charset=utf-8    iexplore:3584
  15  200 HTTP    localhost:52281 /Security/Login?ReturnUrl=%2fImages%2fSettings.png  4,154   private text/html; charset=utf-8    iexplore:3584           
  16  200 HTTP    localhost:52281 /Security/Login?ReturnUrl=%2fScripts%2fjquery.validate.js   4,161   private text/html; charset=utf-8    iexplore:3584
  17  200 HTTP    localhost:52281 /Security/Login?ReturnUrl=%2fScripts%2fjquery.validate.unobtrusive.js   4,173   private text/html; charset=utf-8    iexplore:3584           
  18  200 HTTP    localhost:52281 /Security/Login?ReturnUrl=%2fScripts%2fmodernizr-2.5.3.js   4,161   private text/html; charset=utf-8    iexplore:3584
  19  200 HTTP    localhost:52281 /Security/Login?ReturnUrl=%2fScripts%2fjquery.unobtrusive-ajax.js   4,169   private text/html; charset=utf-8    iexplore:3584           
  </code></pre>
  
  <p>Here is the code in my controller</p>
  
  <pre><code>namespace ChargesDashboard.Controllers
  {
      [Authorize]
      [InitializeSimpleMembership]
      public class SecurityController : Controller
      {
          //
          // GET: /Security/Login
  
          [AllowAnonymous]
          public ActionResult Login(string returnUrl)
          {
              ViewBag.ReturnUrl = returnUrl;
              return View();
          }
          //
          // POST: /Security/Login
  
          [HttpPost]
          [AllowAnonymous]
          [ValidateAntiForgeryToken]
          public ActionResult Login(LoginModel model, string returnUrl)
          {
              if (ModelState.IsValid &amp;&amp; WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
              {
                  return RedirectToLocal(returnUrl);
              }
  
              // If we got this far, something failed, redisplay form
              ModelState.AddModelError("", "The user name or password provided is incorrect.");
              return View(model);
          }
  
          //
          // POST: /Security/LogOff
  
          [HttpPost]
          [ValidateAntiForgeryToken]
          public ActionResult LogOff()
          {
              WebSecurity.Logout();
  
              return RedirectToAction("Index", "Home");
          }
  
          //
          // GET: /Security/Register
  
          [AllowAnonymous]
          public ActionResult Register()
          {
              return View();
          }
  
          //
          // POST: /Account/Register
  
          [HttpPost]
          [AllowAnonymous]
          [ValidateAntiForgeryToken]
          public ActionResult Register(RegisterModel model)
          {
              if (ModelState.IsValid)
              {
                  // Attempt to register the user
                  try
                  {
                      WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
                      WebSecurity.Login(model.UserName, model.Password);
                      return RedirectToAction("Index", "Home");
                  }
                  catch (MembershipCreateUserException e)
                  {
                      ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
                  }
              }
  
              // If we got this far, something failed, redisplay form
              return View(model);
          }
  
          //
          // POST: /Account/Disassociate
  
          [HttpPost]
          [ValidateAntiForgeryToken]
          public ActionResult Disassociate(string provider, string providerUserId)
          {
              string ownerAccount = OAuthWebSecurity.GetUserName(provider, providerUserId);
              ManageMessageId? message = null;
  
              // Only disassociate the account if the currently logged in user is the owner
              if (ownerAccount == User.Identity.Name)
              {
                  // Use a transaction to prevent the user from deleting their last login credential
                  using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.Serializable }))
                  {
                      bool hasLocalAccount = OAuthWebSecurity.HasLocalAccount(WebSecurity.GetUserId(User.Identity.Name));
                      if (hasLocalAccount || OAuthWebSecurity.GetAccountsFromUserName(User.Identity.Name).Count &gt; 1)
                      {
                          OAuthWebSecurity.DeleteAccount(provider, providerUserId);
                          scope.Complete();
                          message = ManageMessageId.RemoveLoginSuccess;
                      }
                  }
              }
  
              return RedirectToAction("Manage", new { Message = message });
          }
  
          //
          // GET: /Account/Manage
  
          public ActionResult Manage(ManageMessageId? message)
          {
              ViewBag.StatusMessage =
                  message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
                  : message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
                  : message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
                  : "";
              ViewBag.HasLocalPassword = OAuthWebSecurity.HasLocalAccount(WebSecurity.GetUserId(User.Identity.Name));
              ViewBag.ReturnUrl = Url.Action("Manage");
              return View();
          }
  
          //
          // POST: /Account/Manage
  
          [HttpPost]
          [ValidateAntiForgeryToken]
          public ActionResult Manage(LocalPasswordModel model)
          {
              bool hasLocalAccount = OAuthWebSecurity.HasLocalAccount(WebSecurity.GetUserId(User.Identity.Name));
              ViewBag.HasLocalPassword = hasLocalAccount;
              ViewBag.ReturnUrl = Url.Action("Manage");
              if (hasLocalAccount)
              {
                  if (ModelState.IsValid)
                  {
                      // ChangePassword will throw an exception rather than return false in certain failure scenarios.
                      bool changePasswordSucceeded;
                      try
                      {
                          changePasswordSucceeded = WebSecurity.ChangePassword(User.Identity.Name, model.OldPassword, model.NewPassword);
                      }
                      catch (Exception)
                      {
                          changePasswordSucceeded = false;
                      }
  
                      if (changePasswordSucceeded)
                      {
                          return RedirectToAction("Manage", new { Message = ManageMessageId.ChangePasswordSuccess });
                      }
                      else
                      {
                          ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
                      }
                  }
              }
              else
              {
                  // User does not have a local password so remove any validation errors caused by a missing
                  // OldPassword field
                  ModelState state = ModelState["OldPassword"];
                  if (state != null)
                  {
                      state.Errors.Clear();
                  }
  
                  if (ModelState.IsValid)
                  {
                      try
                      {
                          WebSecurity.CreateAccount(User.Identity.Name, model.NewPassword);
                          return RedirectToAction("Manage", new { Message = ManageMessageId.SetPasswordSuccess });
                      }
                      catch (Exception e)
                      {
                          ModelState.AddModelError("", e);
                      }
                  }
              }
  
              // If we got this far, something failed, redisplay form
              return View(model);
          }
  
          //
          // POST: /Account/ExternalLogin
  
          [HttpPost]
          [AllowAnonymous]
          [ValidateAntiForgeryToken]
          public ActionResult ExternalLogin(string provider, string returnUrl)
          {
              return new ExternalLoginResult(provider, Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
          }
  
          //
          // GET: /Account/ExternalLoginCallback
  
          [AllowAnonymous]
          public ActionResult ExternalLoginCallback(string returnUrl)
          {
              AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
              if (!result.IsSuccessful)
              {
                  return RedirectToAction("ExternalLoginFailure");
              }
  
              if (OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false))
              {
                  return RedirectToLocal(returnUrl);
              }
  
              if (User.Identity.IsAuthenticated)
              {
                  // If the current user is logged in add the new account
                  OAuthWebSecurity.CreateOrUpdateAccount(result.Provider, result.ProviderUserId, User.Identity.Name);
                  return RedirectToLocal(returnUrl);
              }
              else
              {
                  // User is new, ask for their desired membership name
                  string loginData = OAuthWebSecurity.SerializeProviderUserId(result.Provider, result.ProviderUserId);
                  ViewBag.ProviderDisplayName = OAuthWebSecurity.GetOAuthClientData(result.Provider).DisplayName;
                  ViewBag.ReturnUrl = returnUrl;
                  return View("ExternalLoginConfirmation", new RegisterExternalLoginModel { UserName = result.UserName, ExternalLoginData = loginData });
              }
          }
  
          //
          // POST: /Account/ExternalLoginConfirmation
  
          [HttpPost]
          [AllowAnonymous]
          [ValidateAntiForgeryToken]
          public ActionResult ExternalLoginConfirmation(RegisterExternalLoginModel model, string returnUrl)
          {
              string provider = null;
              string providerUserId = null;
  
              if (User.Identity.IsAuthenticated || !OAuthWebSecurity.TryDeserializeProviderUserId(model.ExternalLoginData, out provider, out providerUserId))
              {
                  return RedirectToAction("Manage");
              }
  
              if (ModelState.IsValid)
              {
                  // Insert a new user into the database
                  using (UsersContext db = new UsersContext())
                  {
                      UserProfile user = db.UserProfiles.FirstOrDefault(u =&gt; u.UserName.ToLower() == model.UserName.ToLower());
                      // Check if user already exists
                      if (user == null)
                      {
                          // Insert name into the profile table
                          db.UserProfiles.Add(new UserProfile { UserName = model.UserName });
                          db.SaveChanges();
  
                          OAuthWebSecurity.CreateOrUpdateAccount(provider, providerUserId, model.UserName);
                          OAuthWebSecurity.Login(provider, providerUserId, createPersistentCookie: false);
  
                          return RedirectToLocal(returnUrl);
                      }
                      else
                      {
                          ModelState.AddModelError("UserName", "User name already exists. Please enter a different user name.");
                      }
                  }
              }
  
              ViewBag.ProviderDisplayName = OAuthWebSecurity.GetOAuthClientData(provider).DisplayName;
              ViewBag.ReturnUrl = returnUrl;
              return View(model);
          }
  
          //
          // GET: /Account/ExternalLoginFailure
  
          [AllowAnonymous]
          public ActionResult ExternalLoginFailure()
          {
              return View();
          }
  
          [AllowAnonymous]
          [ChildActionOnly]
          public ActionResult ExternalLoginsList(string returnUrl)
          {
              ViewBag.ReturnUrl = returnUrl;
              return PartialView("_ExternalLoginsListPartial", OAuthWebSecurity.RegisteredClientData);
          }
  
          [ChildActionOnly]
          public ActionResult RemoveExternalLogins()
          {
              ICollection&lt;OAuthAccount&gt; accounts = OAuthWebSecurity.GetAccountsFromUserName(User.Identity.Name);
              List&lt;ExternalLogin&gt; externalLogins = new List&lt;ExternalLogin&gt;();
              foreach (OAuthAccount account in accounts)
              {
                  AuthenticationClientData clientData = OAuthWebSecurity.GetOAuthClientData(account.Provider);
  
                  externalLogins.Add(new ExternalLogin
                  {
                      Provider = account.Provider,
                      ProviderDisplayName = clientData.DisplayName,
                      ProviderUserId = account.ProviderUserId,
                  });
              }
  
              ViewBag.ShowRemoveButton = externalLogins.Count &gt; 1 || OAuthWebSecurity.HasLocalAccount(WebSecurity.GetUserId(User.Identity.Name));
              return PartialView("_RemoveExternalLoginsPartial", externalLogins);
          }
  
          #region Helpers
          private ActionResult RedirectToLocal(string returnUrl)
          {
              if (Url.IsLocalUrl(returnUrl))
              {
                  return Redirect(returnUrl);
              }
              else
              {
                  return RedirectToAction("Index", "Home");
              }
          }
  
          public enum ManageMessageId
          {
              ChangePasswordSuccess,
              SetPasswordSuccess,
              RemoveLoginSuccess,
          }
  
          internal class ExternalLoginResult : ActionResult
          {
              public ExternalLoginResult(string provider, string returnUrl)
              {
                  Provider = provider;
                  ReturnUrl = returnUrl;
              }
  
              public string Provider { get; private set; }
              public string ReturnUrl { get; private set; }
  
              public override void ExecuteResult(ControllerContext context)
              {
                  OAuthWebSecurity.RequestAuthentication(Provider, ReturnUrl);
              }
          }
  
          private static string ErrorCodeToString(MembershipCreateStatus createStatus)
          {
              // See http://go.microsoft.com/fwlink/?LinkID=177550 for
              // a full list of status codes.
              switch (createStatus)
              {
                  case MembershipCreateStatus.DuplicateUserName:
                      return "User name already exists. Please enter a different user name.";
  
                  case MembershipCreateStatus.DuplicateEmail:
                      return "A user name for that e-mail address already exists. Please enter a different e-mail address.";
  
                  case MembershipCreateStatus.InvalidPassword:
                      return "The password provided is invalid. Please enter a valid password value.";
  
                  case MembershipCreateStatus.InvalidEmail:
                      return "The e-mail address provided is invalid. Please check the value and try again.";
  
                  case MembershipCreateStatus.InvalidAnswer:
                      return "The password retrieval answer provided is invalid. Please check the value and try again.";
  
                  case MembershipCreateStatus.InvalidQuestion:
                      return "The password retrieval question provided is invalid. Please check the value and try again.";
  
                  case MembershipCreateStatus.InvalidUserName:
                      return "The user name provided is invalid. Please check the value and try again.";
  
                  case MembershipCreateStatus.ProviderError:
                      return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
  
                  case MembershipCreateStatus.UserRejected:
                      return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
  
                  default:
                      return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
              }
          }
          #endregion
      }
  }
  </code></pre>
  
  <p>Here is the code in my Login view:</p>
  
  <pre><code>@model ChargesDashboard.Models.LoginModel
  
  @{
      ViewBag.Title = "Log in";
      Layout = "~/Views/Shared/_DashboardLayout.cshtml";
  }
  
  &lt;hgroup class="title"&gt;
      &lt;h1&gt;@ViewBag.Title.&lt;/h1&gt;
  &lt;/hgroup&gt;
  
  &lt;section id="loginForm"&gt;
  &lt;h2&gt;Use a local account to log in.&lt;/h2&gt;
  @using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) {
      @Html.AntiForgeryToken()
      @Html.ValidationSummary(true)
  
      &lt;fieldset&gt;
          &lt;legend&gt;Log in Form&lt;/legend&gt;
          &lt;ol&gt;
              &lt;li&gt;
                  @Html.LabelFor(m =&gt; m.UserName)
                  @Html.TextBoxFor(m =&gt; m.UserName)
                  @Html.ValidationMessageFor(m =&gt; m.UserName)
              &lt;/li&gt;
              &lt;li&gt;
                  @Html.LabelFor(m =&gt; m.Password)
                  @Html.PasswordFor(m =&gt; m.Password)
                  @Html.ValidationMessageFor(m =&gt; m.Password)
              &lt;/li&gt;
              &lt;li&gt;
                  @Html.CheckBoxFor(m =&gt; m.RememberMe)
                  @Html.LabelFor(m =&gt; m.RememberMe, new { @class = "checkbox" })
              &lt;/li&gt;
          &lt;/ol&gt;
          &lt;input type="submit" value="Log in" /&gt;
      &lt;/fieldset&gt;
      &lt;p&gt;
          @Html.ActionLink("Register", "Register", "Security") if you don't have an account.
      &lt;/p&gt;
  }
  &lt;/section&gt;
  
  
  @section Scripts {
      @Scripts.Render("~/bundles/jqueryval")
  }
  </code></pre>
  
  <p>Here's my layout file:</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;html lang="en"&gt;
  &lt;head&gt;
      &lt;meta charset="utf-8" /&gt;
      &lt;title&gt;@ViewBag.Title - Charges Dashboard&lt;/title&gt;
      &lt;link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" /&gt;
      &lt;meta name="viewport" content="width=device-width" /&gt;
      @Styles.Render("~/Content/css")
      @Scripts.Render("~/bundles/modernizr")
  &lt;/head&gt;
  &lt;body&gt;
      &lt;header&gt;
          &lt;div class="content-wrapper"&gt;
          Charges Dashboard    
          &lt;/div&gt;
  
      &lt;/header&gt;
      &lt;div id="body"&gt;
          @RenderSection("featured", required: false)
          &lt;section class="content-wrapper main-content clear-fix"&gt;
              @RenderBody()
          &lt;/section&gt;
      &lt;/div&gt;
      &lt;footer&gt;
          &lt;div class="content-wrapper"&gt;
              &lt;div class="float-left"&gt;
                  &lt;p&gt;
                      &amp;copy; @DateTime.Now.Year &lt;/p&gt;
              &lt;/div&gt;
          &lt;/div&gt;
      &lt;/footer&gt;
      @Scripts.Render("~/bundles/jquery")
      @RenderSection("scripts", required: false)
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>Any ideas?</p>