Кэшировать или не кешировать? А как его кешировать на базовом контроллере в asp.net mvc? - PullRequest
4 голосов
/ 02 октября 2009

Я делаю свой собственный базовый контроллер, так как я хочу передать некоторые данные на главную страницу. Теперь, поскольку это похоже на добавление этого кода к каждому представлению в этом контроллере, он запускается каждый раз.

К тому времени, когда он загружается в первый раз, я думаю, что он ударил мой код по крайней мере дважды. Так что я думал о кешировании. Но в моей книге говорится, что не кешируйте личные данные, так как все увидят.

Так что я не уверен, что делать.

Вот что делает моя пара строк кода:

  1. Находит имя пользователя и отображает его для пользователя.
  2. Найти план пользователя и отобразить его.

Так что мне нужно, чтобы userName выяснил их GUID, чтобы я мог узнать, на какой план они подписались.

Так что я не знаю, как его кешировать, но не всем его раскрываю. Есть ли где-нибудь, чтобы сделать это кеш только для этого пользователя?

Цитата Asp.net mvc framework unleasehd pg 330

Не кэшировать личные данные

Кэширование страницы, содержащей приват Пользовательские данные чрезвычайно опасны. когда страница кэшируется на сервере, та же страница обслуживается всем пользователям. Так, если вы кэшируете страницу, которая отображает номер кредитной карты пользователя, каждый может увидеть номер кредитной карты (не хорошо!).

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

Поскольку эта информация является частной, Вы требуете от пользователя, чтобы войти в систему, прежде чем видя страницу. Другими словами, каждый пользователь должен быть авторизован до Пользователь может просматривать страницу.

Для повышения производительности страница финансовых услуг, вы решили включить кеширование для страницы. Вы добавляете атрибут OutputCache для действие контроллера, которое возвращает стр.

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

В общем случае добавление OutputCache и Авторизовать атрибут для того же действие контроллера открывает безопасность отверстие. Избегайте этого:

Ответы [ 2 ]

2 голосов
/ 02 октября 2009

Лучший способ ответить, следует ли вам что-то кэшировать, - это определить, действительно ли это влияет на производительность вашего сайта. С актуальными показателями. Не угадай Если это ничего не ранит и все кажется отзывчивым, то я бы сказал, работайте над чем-то другим, пока не возникнет необходимость. «Опасная оптимизация - корень всего зла», - было сказано раз или два:)

Если вы решите кэшировать данные, я не уверен, что вы имеете в виду, что всем будет разрешено их видеть? Если вы имеете в виду инфраструктуру кэширования ASP.NET (HttpContext.Current.Cache), то она живет в памяти вашего сервера и является полностью нестабильной (она может быть стерта в любое время, если нагрузка на нее достигнет). Поэтому убедитесь, что вы помните об этом, и всегда проверяйте на ноль. Чтобы использовать его, вы можете просто использовать Cache.Insert(), и у него есть пара перегрузок для настройки ваших предпочтений кэширования.

Теперь, если вы говорите о кэшировании чего-либо с помощью файлов cookie браузера, это уже другая история. Cookie-файлы действительно хранятся в браузере, и если вы не укажете HttpOnly для cookie-файла, его можно прочитать с помощью javascript (что является проблемой только при наличии где-либо уязвимости XSS - поскольку злонамеренный пользователь может использовать javascript для «phone-home» "личные файлы cookie пользователей.) Так что не помещайте ничего в личный файл cookie, если это не является абсолютно необходимым, и если вы это сделаете, вам следует указать HttpOnly и принять соответствующие меры для защиты ваших пользователей.

Вам определенно следует больше узнать о XSS и других распространенных проблемах безопасности HTTP, если безопасность вас беспокоит. (Так и должно быть:)

ОБНОВЛЕНО для решения вопроса редактирования, касающегося кэширования вывода:

Ладно, вы специально обращались к кешированию вывода. Действительно, в этой книге упоминается дыра в безопасности, которую я считаю, была исправлена ​​до выхода MVC 1. Атрибут Authorize должен быть достаточно умным, чтобы правильно обрабатывать кэширование вывода, когда эти два атрибута используются совместно. Возможно, эта книга была написана во время предварительного просмотра и больше не актуальна.

Я цитирую следующее от Стива Сандерсона (автора Pro ASP.NET MVC Framework)

Обновление: начиная с бета-версии, Фильтр [Authorize] теперь делает некоторые умный обман, чтобы сотрудничать с ASP.NET кеширование вывода. В частности, он регистрирует делегата, используя HttpCachePolicy.AddValidationCallback (), чтобы он мог перехватить будущий кеш Хиты и сказать кэширование вывода ASP.NET не использовать кеш при [Авторизации] отклонил бы запрос. Это решает проблема кэширования вывода ASP.NET в обход фильтра [Авторизация]. Если ты собираешься написать свой фильтр авторизации, обязательно вывести его из AuthorizeAttribute так Вы можете унаследовать это полезное поведение.

Обратите внимание, что это не останавливает ASP.NET Кэширование вывода в обход любого из ваши другие фильтры действий, и это не добавляет поддержку частичного кэширование. Если это проблема для вас тогда подумайте об использовании Вместо этого [ActionOutputCache] (ниже).

Было бы целесообразно прочитать его статью (и его книгу, в этом отношении): http://blog.codeville.net/2008/10/15/partial-output-caching-in-aspnet-mvc/

1 голос
/ 02 октября 2009

Ваши классы Controller имеют только жизненный цикл, который простирается от запроса-действия до визуализации представления. Вам действительно нужно кэшировать эти данные? Просто предоставьте данные в вашем объекте Model. Запросы не кажутся достаточно сложными, и вдобавок к этому большинство поставщиков РСУБД, как правило, выполняют много операций кэширования запросов самостоятельно.

HTTP - это протокол без сохранения состояния, означающий, что после запроса ваш веб-сервер забывает все об указанном запросе. Чтобы обойти это отсутствие состояния, asp.net предлагает объекты Application и Session. Приложение глобально доступно для всех запросов, а Session привязан к одному IP. Размещение каких-либо данных обычно является последним средством или частью схемы для кэширования данных, которые действительно сильно загружаются.

Поток в ASP.NET MVC примерно

  • URL запрашивается
  • Контроллер называется
  • Действие называется
  • Действие вызывает модель для данных (имя пользователя / план пользователя)
  • Действие устанавливает данные в модели представления
  • Действие вызывает желаемое представление с данными в модели представления
  • Вид отображается.

Установка данных для модели представления уже является «частной», поэтому я не уверен, откуда берется необходимость в кэшировании. Возможно, я неправильно понимаю вопрос?

Редактировать

Хорошо, сначала прости меня, если мой пост был немного самонадеянным. Я действительно думаю, что ваш код вообще не должен входить в конструктор вашего базового конструктора. Вы не передаете свой контроллер на просмотр в конце концов.

Хорошей практикой является передача типизированных ViewModels. Скажите, что это ваше определение на вашем сайте. Master

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MyNS.BaseViewDataModel>" %>

И это определение, скажем, вашей справочной страницы. Просмотр:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MyNS.HelpViewDataModel>" %>

Затем вы можете создать BaseViewDataModel

namespace MyNS
{
    public class BaseViewDataModel

И ваша HelpViewDataModel

namespace MyNS
{
    public class HelpViewDataModel : BaseViewDataModel 
    {

Тогда в вашей помощи соответствующее действие контроллера

[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Index()
{
    var viewDataModel = new HelpViewDataModel ();
            viewDataModel.HelpText = "something";
            ..
            ..
    return View(viewDataModel);
}

Теперь вы можете создавать экземпляр guid и пользовательского плана в конструкторе BaseViewDataModel, и он будет вызываться только для действий, которые фактически создают подкласс BaseViewDataModel.

А ваши представления безопасны от типов, что значительно повышает производительность, поскольку мы набрали те представления, которые мы теперь можем назвать

<%= this.Model.HelpText %>

В представлении справки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...