Изображение У меня есть представление, которое кэшируется с атрибутом OutputCache, но мне все еще нужно увеличить счетчик, который записывает, что страница была просмотрена, как я могу это сделать?
Я думал о создании собственного пользовательского атрибута ActionFilterAttribute и использовании порядка выполнения Action Filter для записи этого ... но я не уверен, что он будет работать.
например.
[IncrementViewCountFilter(Order=1)]
[OutputCache(Duration=60,Order=2)]
public ActionResult Index(int questionId)
{ ... }
Во-первых, я предполагаю, что если вызывается OutputCache и страница кэшируется, то код контроллера не будет запущен.
Следующая проблема, которую я предполагаю, заключается в том, что IncrementViewCountFilter не будет знать о questionId, поэтому как он будет знать, что увеличивать (потому что он выполняется до выполнения основного кода индекса).
Во-вторых, если IncrementViewCountFilter действительно знал questionId ... и он получает много обращений, вы бы не хотели, чтобы он все время записывал в БД ... но только когда он достигает определенного числа ... и затем вы сбрасываете ' выход.
У кого-нибудь есть мысли?
Ну, у вас есть несколько вариантов.
Кеширование пончиков
Один из вариантов на стороне сервера - «Кеширование пончиков». Кэширование пончиков позволяет кэшировать большую часть страницы, а некоторые части страницы не кэшировать (дыра в середине пончика). Кеширование пончиков описано здесь , и я использовал его с большим успехом.
Основанный на изображении трекер
Другой вариант заключается в том, чтобы изображение на странице фактически загружало действие на стороне сервера, которое записывает попадание. Это будет выглядеть как
<img src="/controller/action">
на странице, где действие подает пустое изображение в конце.
Отслеживание на стороне клиента
Последний вариант - отслеживание на стороне клиента - где некоторый скрипт выполняется на стороне клиента и использует AJAX для вызова чего-либо на сервере для записи попадания. Google использует что-то подобное для своего пакета Google Analytics. Если вы находитесь в том же домене, что и ваш механизм отслеживания ... например, если ваша главная страница:
http://www.domain.com/home/action
и трекер включен
http://www.domain.com/tracking/action
тогда ты должен быть в порядке.
Это становится непросто, когда ваш трекер находится в другом домене (вам нужно справиться с этим, используя JSONP или какой-либо другой механизм, который обеспечивает относительно безопасный межсайтовый скриптинг).
Я не знаю, что касается MVC, но если бы я делал это в WebForms, это звучало бы так, как если бы я был кандидатом на замену выходного кеша, или на кеширование пончиков.
Фильтр может получить questionId из ActionExecutingContext.ActionParameters, который передается OnActionExecuting. Что касается кеширования, то подсчитывает количество попаданий, ну и используйте кеш. :)
Вы также можете использовать HttpModule, который является хорошим вариантом, поскольку его можно использовать для страниц и других ресурсов, которые не используют конвейер MVC. Я использую комбинацию кеширования пончиков (http://mvcdonutcaching.codeplex.com/), фильтра MVC и модуля HttpModule для записи всех видов аналитики для кэшированных страниц.