0

我有一个带有大约 8 或 9 个操作方法的 HomeController。

其中大约 7 种方法需要检查用户是否有特殊设置,以查看是否允许他们访问这些方法和相关视图。

如果不是,它们将被重定向回通用操作方法和视图。

public class HomeController : Controller
{
    public ActionResult Index() {
       UserManager um = new UserManager();
       um.Punter p = um.GetPunter(User.Identity.Name);
       return View(p);
    }
    public ActionResult PunterList() {
       UserManager um = new UserManager();
       um.Punter p = um.GetPunter(User.Identity.Name);
       if (p.isPunter) {
           return RedirectToAction("Index", "Home");
       } else {
           return View(p);
       }
    }
}

'PunterList' 中的检查是在其他操作方法中完成的,我正在考虑创建一个 FilterAttribute 来执行此检查。根据以下内容:

public class NoPunterAttribute : FilterAttribute, IActionFilter {
    public void OnActionExecuting(ActionExecutingContext filterContext) {
       UserManager um = new UserManager();
       um.Punter p = um.GetPunter(User.Identity.Name);
       if (p.isPunter) {
           filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary { { "controller", "Home" }, { "action", "Index" } });
       }
    }
    public void OnActionExecuted(ActionExecutedContext filterContext) { }
}

然后将此属性放在此类用户无法访问的 Action 方法上。

[NoPunter]
    public ActionResult PunterList() {
       UserManager um = new UserManager();
       um.Punter p = um.GetPunter(User.Identity.Name);
       return View(p);
    }

这会将这段代码放在适当的1位置,但是UserManager.GetPunter如果User.isPunter=false. 也许这对于 MVC Web 应用程序的性能或内存节约来说不是一个好主意。

好处是在请求管道中更早地进行检查,但也许在操作方法内部调用的方法意味着 .GetPunter 只会被调用一次,但会沿着请求管道更远。不确定这一点,在早期与性能/内存问题上存在分歧。

任何建议或想法都会很有趣。大概这取决于里面做了什么UserManager.GetPunter。此调用中有一些缓存,但它会重新查询缓存。

4

1 回答 1

0

您可以编写一个自定义授权属性,将 Punter 作为您操作的参数注入:

public class HomeController : Controller
{
    public ActionResult Index() 
    {
        UserManager um = new UserManager();
        um.Punter p = um.GetPunter(User.Identity.Name);
        return View(p);
    }

    [NoPunterAuthorize]
    public ActionResult PunterList(Punter punter) 
    {
       return View(punter);
    }
}

和自定义授权属性:

public class NoPunterAuthorize: AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var authorized = base.AuthorizeCore(httpContext);
        if (!authorized)
        {
            return false;
        }

        var um = new UserManager();
        var p = um.GetPunter(httpContext.User.Identity.Name);
        var routeData = httpContext.Request.RequestContext.RouteData;
        routeData.Values["punter"] = p;
        return !p.IsPunter;
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        filterContext.Result = new RedirectToRouteResult(
            new RouteValueDictionary 
            { 
                { "controller", "Home" }, 
                { "action", "Index" } 
            }
        );
    }
}
于 2013-06-20T10:49:19.327 回答