0

Я использую помощник MvcSiteMapProvider Html Helper для создания навигационной панели. Содержимое навигационной панели зависит от прав посетителей, поэтому я использую обрезку безопасности, чтобы отображать только те материалы, на которые разрешено лицо. Для повышения производительности я пытаюсь кэшировать эту навигационную панель.MVCSiteMapProvider: использование обрезки безопасности с кешем ouput возвращает пустой файл Sitemap

навигационная панель создаются в частичном виде со следующим содержанием:

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

Внутри макета файла он называется методом действия, который возвращает частичный вид:

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

Кэширования работ на корневой странице файла Sitemap. Однако, когда длительность кеша заканчивается, и метод действия вызывается с более глубоких уровней, карта сайта не возвращается. Когда я отключу обрезку безопасности или кеширование вывода, она отлично работает на всех уровнях.

Возможно ли, что метод действия, который возвращает navbar, вызывается, когда данные авторизации недоступны и, следовательно, возвращает поврежденную карту сайта?

ответ

0

Если вы проанализируете source for AuthorizeAttribute, вы заметите, что он не предназначен для работы с дочерними действиями, которые выводятся в кеш (они идут на большие длины, чтобы обеспечить, что child actions that are output cached will throw an exception).

Конечно, это также не сработает правильно, если у вас есть пользовательский AuthorizeAttribute, который переопределяет OnAuthorization, который не дублирует эту важную логику.

Однако, есть несколько вещей, которые вы можете сделать, чтобы улучшить производительность при использовании ролей безопасности:

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

Для получения более подробной информации см. this discussion.

+0

Означает ли это, что только действие, использующее макет, использует действие 'AuthorizeAttribute', а не дочернее действие? –

+0

Я никогда не пытался использовать 'MvcSiteMapProvider' с кэшированием вывода. Я предполагаю, что это, вероятно, не сработает. Он должен быть динамичным и изменяться с каждым запросом. Кэширование вывода означает, что объект 'SiteMap' никогда не будет вызван, и ни одна из логических функций не будет выполняться, которая должна выполняться при каждом запросе, - эффективно минуя службы обеспечения безопасности и видимости. – NightOwl888