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

yar*_*lty 2 asp.net-mvc returnurl razor formsauthentication

我已经阅读了很多关于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???
Run Code Online (Sandbox Code Playgroud)

登录视图:

@using (Html.BeginForm()){...} //new { returnUrl } ???
Run Code Online (Sandbox Code Playgroud)

登录获取ActionResult:

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

登录发布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);
}
Run Code Online (Sandbox Code Playgroud)

解决方案 感谢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>
Run Code Online (Sandbox Code Playgroud)

ALSO 按照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>
Run Code Online (Sandbox Code Playgroud)

小智 5

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

这样的事情应该可以解决问题

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


小智 5

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

@{
    ViewBag.Title = "My Page";
    ViewBag.ReturnUrl = "/Home/Live";
}
Run Code Online (Sandbox Code Playgroud)

在_LoginPartial中:

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