我怎么在MVC 4中使用ReturnUrl = ViewBag.ReturnUrl

Ler*_*ica 39 asp.net-mvc-routing asp.net-mvc-4 simplemembership

我正在研究'ASP.NET MVC 4'应用程序.我正在使用/学习SimpleMembershipProvider,并尝试坚持VS2012使用Internet template(如果我没有记错的话,创建的默认逻辑,开箱即用的'SimpleMembershipProvider').

我被困在AccountController我无法想象的地方,我怎么能使用这个方法:

private ActionResult RedirectToLocal(string returnUrl)
        {
            if (Url.IsLocalUrl(returnUrl))
            {
                return Redirect(returnUrl);
            }
            else
            {
                return RedirectToAction("Index", "Home");
            }
        }
Run Code Online (Sandbox Code Playgroud)

根据我的理解,整个想法是重定向到您决定登录的位置(正是我想要完成的).我看了一下它在视图中的使用方式:

@using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl }))
Run Code Online (Sandbox Code Playgroud)

寻找一个实际ViewBag.ReturnUrl设置了一些值的地方,我这里只有这个方法:

[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
    ViewBag.ReturnUrl = returnUrl;
    return View();
}
Run Code Online (Sandbox Code Playgroud)

而且我对我应该如何获得位置/网址感到非常困惑.我设置了一些断点,我从来没有见过returnUrl不同的东西null,在这种情况下对我来说似乎很合乎逻辑,因为它在任何地方都没有价值(除非我当然错过了一些东西).

所以我真的无法弄清楚这是如何工作的.我发布以上内容只是为了表明我试图做我的作业,我尽可能多地调查,但我没有找到答案所以我在这里问.你能提供关于它如何实际工作的解释/例子吗?

Kev*_*ans 62

使用表单身份验证并且用户未经过身份验证或授权时,ASP.NET安全管道将重定向到登录页面并作为参数传递给查询字符串,returnUrl等于重定向到登录页面的页面.登录操作会获取此参数的值并将其放入ViewBag中,以便将其传递给View.

    [AllowAnonymous]
    public ActionResult Login(string returnUrl)
    {
        ViewBag.ReturnUrl = returnUrl;
        return View();
    }
Run Code Online (Sandbox Code Playgroud)

然后,View将此值存储在表单中,如View中的此行代码所示.

@using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl }))
Run Code Online (Sandbox Code Playgroud)

它存储在View中的原因是,当用户在输入用户名和密码后执行提交时,处理回发的控制器操作将有权访问此值.

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Login(LoginModel model, string returnUrl)
    {
        if (ModelState.IsValid && 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);
    }
Run Code Online (Sandbox Code Playgroud)

如果模型状态有效并且通过调用WebSecurity.Login方法对它们进行身份验证,那么它将调用RedirectToLocal方法,其值为returnUrl,该值来自View,最初来自创建View的登录操作.

RETURNURL值为空,如果用户不重定向到登录页面时,他们只需点击登录链接在页面的默认布局上的情况.在这种情况下,用户将在成功登录后重定向到主页.returnUrl的全部目的是在用户进行身份验证/授权之前自动将用户发送回他们尝试访问的页面.


Dav*_*trg 13

那是因为默认的ASP.NET MVC模板使用Forms身份验证,控制器使用[Authorize]属性进行修饰:

<authentication mode="Forms">
  <forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>

[Authorize]
public class AccountController : Controller
{
    //...
}
Run Code Online (Sandbox Code Playgroud)

这意味着如果用户未经过身份验证,则会将其重定向到forms元素的LoginUrl属性中定义的登录页面.

在重定向,FormsAuthentication这是一个HttpModule将追加这是自动请求的查询字符串的URL.

因此,如果您导航到/Account/Login,则不会在查询字符串中获得任何内容,因为它使用[AllowAnonymous]属性进行修饰.但是如果你导航到/Account/Manage你会注意到查询字符串中的returnUrl变为/Account/Manage (/Account/Login?ReturnUrl=%2fAccount%2fManage)

因此,您没有设置returnUrl,框架会为您执行此操作,您只需使用它AccountController来了解用户在进行身份验证后重定向的位置.