MVCSiteMapProvider:对输出缓存使用安全修整 returns 空站点地图

MVCSiteMapProvider: Using security trimming with ouput cache returns empty sitemap

我正在使用 MvcSiteMapProvider Html 助手来创建导航栏。导航栏的内容取决于访问者的权限,因此我使用安全修整来仅显示该人员获得授权的内容。为了提高性能,我正在尝试缓存此导航栏。

导航栏是在局部视图中创建的,内容如下:

@Html.MvcSiteMap().Menu("MenuHelper", new { name = "MainMenu" })

在布局文件中,它由 returns 局部视图的操作方法调用:

[System.Web.Mvc.OutputCache(Duration = 10, VaryByCustom = "User")]
[ChildActionOnly]
public ActionResult MainMenu()
{
    return PartialView("MainMenu");
}

站点地图的根页面的缓存工作正常。但是,当缓存持续时间用完并且从更深层次调用操作方法时,不会返回任何站点地图。 当我禁用安全修整或输出缓存时,它在所有级别都工作得很好。

当授权数据不可用并因此 returns 损坏站点地图时,是否可以调用 returns 导航栏的操作方法?

如果你分析source for AuthorizeAttribute, you will note that it is not designed to work with child actions that are output cached (they go to some great lengths to ensure that child actions that are output cached will throw an exception)。

当然,如果您有自定义 AuthorizeAttribute 覆盖 OnAuthorization 且不重复此重要逻辑,它也不会正常工作。

但是,在使用安全修整时,您可以采取一些措施来提高性能:

  1. 确保您的 injection constructors are simple,尤其是在您的控制器上。如果您的构造函数中有繁重的处理,它确实会减慢速度(有或没有 MvcSiteMapProvider,但 Security Trimming 使这一点更加明显)。
  2. 如果这不足以改善事情并且您没有使用自定义 AuthorizeAttribute,您可以使用 roles attribute/property 将您的角色逻辑复制到 SiteMap 中并删除来自您的配置的 AuthorizeAttributeAclModule(仅限外部 DI)。

有关详细信息,请参阅 this discussion