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

时间:2013-11-21 14:29:27

标签: asp.net-mvc-4 asp.net-mvc-routing 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");
            }
        }

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

@using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl }))

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

[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
    ViewBag.ReturnUrl = returnUrl;
    return View();
}

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

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

3 个答案:

答案 0 :(得分:61)

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

    [AllowAnonymous]
    public ActionResult Login(string returnUrl)
    {
        ViewBag.ReturnUrl = returnUrl;
        return View();
    }

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

@using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl }))

它存储在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);
    }

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

如果未将用户重定向到登录页面, returnUrl 值将为null,就像他们只是在默认布局中单击页面顶部的登录链接一样。在这种情况下,用户将在成功登录后重定向到主页。 returnUrl 的全部目的是在用户进行身份验证/授权之前自动将用户发送回他们尝试访问的页面。

答案 1 :(得分:12)

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

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

[Authorize]
public class AccountController : Controller
{
    //...
}

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

在重定向期间,FormsAuthentication HttpModule将自动追加查询字符串中请求的网址。

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

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

答案 2 :(得分:4)

当未经身份验证的用户尝试进入需要身份验证的应用程序部分时,returnUrl就会出现。未经身份验证的用户请求的网址基本上存储在returnUrl

您可以浏览PluralSight tutorial: Building Applications with ASP.NET MVC 4