MVCSiteMapProvider: при использовании усечения безопасности с выходным кешем возвращается пустая карта сайта
Я использую MvcSiteMapProvider Html Helper для создания панели навигации. Содержимое панели навигации зависит от прав посетителя, поэтому я использую усечение безопасности, чтобы отображать только те материалы, на которые этот человек имеет права. Для повышения производительности я пытаюсь кешировать эту навигационную панель.
Панель навигации создается в частичном виде со следующим содержанием:
@Html.MvcSiteMap().Menu("MenuHelper", new { name = "MainMenu" })
Внутри файла макета он вызывается методом действия, который возвращает частичное представление:
[System.Web.Mvc.OutputCache(Duration = 10, VaryByCustom = "User")]
[ChildActionOnly]
public ActionResult MainMenu()
{
return PartialView("MainMenu");
}
Кэширование прекрасно работает на корневой странице карты сайта. Однако, когда продолжительность кэша заканчивается и метод действия вызывается из более глубоких уровней, карта сайта не возвращается. Когда я отключаю усечение безопасности или кэширование вывода, оно отлично работает на всех уровнях.
Возможно ли, что метод действия, который возвращает панель навигации, вызывается, когда данные авторизации недоступны и, следовательно, возвращает поврежденную карту сайта?
1 ответ
Если вы проанализируете источник дляAuthorizeAttribute
вы заметите, что он не предназначен для работы с дочерними действиями, которые выводятся в кеширование (они идут на большую длину, чтобы гарантировать, что дочерние действия, которые выводятся в кеширование, будут вызывать исключение).
Конечно, это также не будет работать правильно, если у вас есть AuthorizeAttribute
что переопределяет OnAuthorization
это не дублирует эту важную логику.
Тем не менее, есть несколько вещей, которые вы можете сделать для повышения производительности при использовании Security Trimming:
- Убедитесь, что ваши конструкторы инъекций просты, особенно на ваших контроллерах. Если у вас тяжелая обработка в ваших конструкторах, это может сильно замедлить работу (с или без
MvcSiteMapProvider
, но Security Trimming делает это гораздо более очевидным). - Если это не улучшит вещи достаточно, и вы не используете кастом
AuthorizeAttribute
Вы могли бы использоватьroles
атрибут / свойство, чтобы дублировать логику вашей роли в SiteMap и удалитьAuthorizeAttributeAclModule
из вашей конфигурации (только внешний DI).
Смотрите это обсуждение для более подробной информации.