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:

  1. Убедитесь, что ваши конструкторы инъекций просты, особенно на ваших контроллерах. Если у вас тяжелая обработка в ваших конструкторах, это может сильно замедлить работу (с или без MvcSiteMapProvider, но Security Trimming делает это гораздо более очевидным).
  2. Если это не улучшит вещи достаточно, и вы не используете кастом AuthorizeAttributeВы могли бы использовать roles атрибут / свойство, чтобы дублировать логику вашей роли в SiteMap и удалить AuthorizeAttributeAclModule из вашей конфигурации (только внешний DI).

Смотрите это обсуждение для более подробной информации.

Другие вопросы по тегам