MVC基于角色的路由澄清

时间:2012-12-04 12:57:50

标签: asp.net-mvc-3 asp.net-mvc-routing asp.net-mvc-areas

一个很长的解释结束时的小问题......

假设属于Admin Role的Admin User和属于User Role的Regular User尝试访问Index页面,并在Global.asax中注册了以下路由。

 routes.MapRoute(
     "Default", // Route name
     "{controller}/{action}/{id}", // URL with parameters
      new { controller = "Home", action = "Index", id = UrlParameter.Optional }, 
      new[] {"tst.Controllers"}
 );

在HomeController中,索引操作方法使用Authorize属性进行修饰。

[Authorize]
public ActionResult Index()
{
    ViewBag.Message = "Welcome to ASP.NET MVC!";

    return View();
}

强制匿名用户登录。

如果管理员用户使用他/她的凭据登录,我想将他/她重定向到位于管理区域的HomeController中的索引操作方法。

如果普通用户登录,我想将他/她重定向到位于用户区域的HomeController中的索引操作方法。

我在UserAreaRegistration.cs中有以下代码

public override void RegisterArea(AreaRegistrationContext context)
{
  context.MapRoute(
  "User", 
  "Profile/{action}", 
  new { area = AreaName, Controller = "Home", action = "Index" }, 
  new { RoleConstraint = new RoleConstraint()},
  new[]{ "tst.Areas.User.Controllers"}
  );
}

以及AdminAreaRegistration.cs的以下代码

public override void RegisterArea(AreaRegistrationContext context)
{
  context.MapRoute(
  "Admin", 
  "Profile/{action}", 
  new { area = AreaName, Controller = "Home", action = "Index" }, 
  new { RoleConstraint = new RoleConstraint()},
  new[]{ "tst.Areas.Admin.Controllers"}
  );
}

RoleConstraint的定义如下

public class RoleConstraint: IRouteConstraint
{
    public bool Match(
        HttpContextBase httpContext, 
        Route route, 
        string parameterName, 
        RouteValueDictionary values, 
        RouteDirection routeDirection)
    {
        RoleProvider rp = new tst.Providers.CustomRoleProvider();
        string[] roles = rp.GetRolesForUser(httpContext.User.Identity.Name);
        if (roles != null && roles.Length > 0)
        {
            string roleName = roles[0];
            string areaName = route.Defaults["area"].ToString();
            return areaName == roleName;            
        }
        return false;
    }
}

主Controllers文件夹中AdminController中的库存标准LogOn Action Method ...

 [HttpPost]
 public ActionResult LogOn(LogOnModel model, string returnUrl)
 {
   if (ModelState.IsValid)
   {
     if (Membership.ValidateUser(model.UserName, model.Password))
     {
       FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
       if (Url.IsLocalUrl(returnUrl) 
           && returnUrl.Length > 1 
           && returnUrl.StartsWith("/")
           && !returnUrl.StartsWith("//") 
           && !returnUrl.StartsWith("/\\"))
       {
           return Redirect(returnUrl);
       }
       else
       {
           return RedirectToAction("Index", "Home");
       }
     }
     else
     {
       ModelState.AddModelError("", "The user name or password is incorrect.");
     }
   }

   // If we got this far, something failed, redisplay form
   return View(model);
 }

问题: 我是否正确地认为,当管理员/常规用户被验证时,他/她必须在上面的代码片段中重定向到此行

return RedirectToAction("Index", "Home");  

到适当的索引操作方法(读取:相应区域中的索引操作方法)。

如果是这样,我想知道如何。

我很困惑,因为涉及一个常量字符串“Profile”,它不是涉及动作方法和控制器名称的常见内容。 “个人资料”既不是控制者,也不是行动方法。

受此帖的启发 MVC role-based routing

1 个答案:

答案 0 :(得分:0)

而不是

return RedirectToAction("Index", "Home");  
在LogOn Action Method中,我将其替换为

return Redirect("/Profile");

它奏效了!!!

然而,我不明白的是,当我单击Log Off时,它会在主Views文件夹中呈现Index页面。所以我必须再次单击LogOff才能返回LogOn页面。