Статьи

Программная очистка кэша ASP.Net для веб-форм и страниц MVC

Кэширование на уровне страниц для веб-форм ASP.Net и веб-сайтов MVC довольно круто, потому что оно позволяет вам реализовать нечто довольно сложное; многоуровневое кэширование, без необходимости понимать слишком много о кэшировании или даже писать много кода. Но что, если вы хотите очистить кэшированную страницу ASP.net до истечения срока ее действия?

В компьютерных науках есть только две сложные вещи: аннулирование кэша и именование.

—  Мартин Фаулер

Какое кэширование страниц стремится достичь

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

ASP.Net Web Forms и ASP.Net MVC делают это довольно тривиальной задачей, скрывая сложность поставщиков кеша за простыми атрибутами для ваших .aspx-страниц или действий контроллера:

Пример кэширования вывода страницы WebForms:

<%@ OutputCache Duration="300" VaryByParam="productId" %>

Кэширование контроллера ASP.net MVC:

[OutputCache(Duration = 300, VaryByParam = "prodId")]
public ActionResult ProductDetails(string prodId)
{
...
}

Вышеприведенное замечательно, потому что это просто, но вы заметите одну ключевую вещь:

Я установил срок действия кэша до 300 секунд.

Это в первую очередь потому, что я хочу, чтобы контент время от времени извлекался из источника  на случай, если что-то изменилось .

Я использовал 300 секунд, но на самом деле время может быть несущественным — я просто установил произвольное число, которое, по моему мнению, будет соответствовать моим потребностям.

Это на самом деле не использует кеш, так как он может использоваться во многих сценариях, основной из которых происходит в период, когда мой сайт не обновляется, а содержимое меняется только раз в несколько дней / недель / месяцев.

Инструмент .Net пытается разрешить такие ситуации, имея поддержку поставщиков, таких как SQLCacheDependency, который  вы можете добавить в свое приложение.

Но поставщик кеша SQL или даже  CustomCacheProvider  не дают вам точного управления зернистостью, которое вам действительно нужно: возможность программно удалять кэшированные страницы на уровне страницы, элемента управления, действия или дочернего действия.

Как и большинство замечательных вещей: просто и элегантно

ASP.net поддерживает это из коробки — вы просто не слышите об этом много.

Вы можете указать среде выполнения удалить кэшированные страницы и элементы управления просто с помощью очень простого рекурсивного API, который ссылается на его относительный URL-адрес.

// remove any webforms cached item with the wildcard default.aspx*
HttpResponse.RemoveOutputCacheItem("/default.aspx");
// just remove the webforms product page with the prodId=1234 param
HttpResponse.RemoveOutputCacheItem("/product.aspx?prodId=1234");
// remove my MVC controller action's output
HttpResponse.RemoveOutputCacheItem(Url.Action("details", "product", new { id = 1234 }));

Вы заметите, что для ссылки на кеш страницы MVC я использовал   помощник Url.Action , и я рекомендую это, поскольку он использует ту же маршрутизацию MVC, что и поставщик кеша — обычно выбирает первый найденный маршрут. Использование помощника Url.Action означает, что предоставленный вами URL-адрес следует по тому же пути, обратному пути провайдера кэша.

Для дочерних действий MVC в настоящее время я не знаю, как очистить кэши отдельных элементов управления. Дочерние действия контроллера MVC хранятся в  ChildActionCache .

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

OutputCacheAttribute.ChildActionCache = new MemoryCache("NewRandomStringNameToClearTheCache");

Очевидно, это довольно агрессивный подход, но если вы хотите сделать это более детально, попробуйте взломать кэш пончиков MVC проекта с открытым исходным кодом   .