将ActionLink中的returnUrl从视图传递到重定向回视图的登录表单

时间:2014-04-02 03:39:19

标签: asp.net-mvc razor formsauthentication returnurl

我已经阅读了许多关于 returnUrl 的SO帖子,因为它与默认情况下[authorize] MyController的表单身份验证有关,但我还没有阅读任何关于简单地传递returnUrl的内容,其中唯一的身份验证需要在[HttpPost]之后放置一个登录或注册表单和匿名用户。 在这种情况下,我希望重定向来自原始链接并传递给通过表单身份验证对用户进行身份验证的操作。此重定向应该使用户返回到正在查看的页面1)单击注册或登录ActionLinks然后2)成功提交表单。这是在开发服务器上,因此HTTPS不是ATM的要求。

以下是没有必要语法/代码的元素,用于传递returnUrl

_LoginPartial:

<li>@Html.ActionLink("Register", "Register", "Account", routeValues: null}, htmlAttributes: new { id = "registerLink" })</li> //returnUrl???
<li>@Html.ActionLink("Log in", "Login", "Account", routeValues: null, htmlAttributes: new { id = "loginLink" })</li> // returnUrl???

登录视图:

@using (Html.BeginForm()){...} //new { returnUrl } ???

登录获取ActionResult:

[AllowAnonymous]
public ActionResult Login(string returnUrl)
{   
    //There is other ways to store the route
    TempData["ReturnUrl"] = returnUrl;
    return View();
}

登录发布ActionResult:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model)
{
    if (ModelState.IsValid && WebSecurity.Login(model.UserName, model.Password,     persistCookie: model.RememberMe))
    {
        return RedirectToLocal(TempData["ReturnUrl"].ToString());
    }

    // If we got this far, something failed, redisplay form
    ModelState.AddModelError("", "The user name or password provided is incorrect.");
    return View(model);
}

解决方案 感谢SlightlyMoist我能够解决这个问题。虽然代码规模较小,但ViewContext.RouteData.Values["key"]的能力和专有技术似乎是非常宝贵的IMO。因此,根据SM进行的唯一修改是在 _LoginPartial 视图的ActionLinks内完成的:

<li>
@Html.ActionLink("Register", "Register", "Account", routeValues: new {@returnUrl = Url.Action(ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), ViewContext.RouteData.Values["id"])}, htmlAttributes: new { id = "registerLink" })
</li>

<li>
@Html.ActionLink("Log in", "Login", "Account", routeValues: new {@returnUrl = Url.Action(ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), ViewContext.RouteData.Values["id"])}, htmlAttributes: new { id = "loginLink" })
</li>

同时 再次按照SM,ViewContext.HttpContext.Request.Url.PathAndQuery也适用:

<li>
@Html.ActionLink("Register", "Register", "Account", routeValues: new {@returnUrl = ViewContext.HttpContext.Request.Url.PathAndQuery},htmlAttributes: new { id = "registerLink" })
</li>

2 个答案:

答案 0 :(得分:5)

只需在登录操作链接中将当前路由/ URL解析为routeValue。

这样的事情可以解决问题

@Html.ActionLink("Login", "Login", "Account", 
    new {@returnUrl = Url.Action(ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString())})

答案 1 :(得分:5)

类似的想法,但我只是在视图中添加了ViewBag.ReturnUrl,并修改了Register和Login方法。这是因为并非所有登录和注册位置都希望返回到页面,这样您就可以按视图控制视图。

@{
    ViewBag.Title = "My Page";
    ViewBag.ReturnUrl = "/Home/Live";
}

在_LoginPartial中:

@Html.ActionLink( "Log in", "Login", new { area = "", controller = "Account", ReturnUrl=ViewBag.ReturnUrl }, new { id = "loginLink" } )