Как реализовать кэширование VaryByCustom?
Я пытаюсь реализовать функциональность для кэширования определенных страниц в зависимости от хоста. Это потому, что у меня может быть несколько версий страницы, которые имеют одинаковые параметры, и где единственное различие в терминах запроса - это запрашиваемый хост.
Так, например, эти два URL будут запрашивать одну и ту же страницу, но они оформлены по-разному:
http://www.a.com/something/specific
а также
http://www.b.com/something/specific
Я иду через пример, изложенный здесь:
http://msdn.microsoft.com/en-us/library/5ecf4420%28v=VS.90%29.aspx
но это не имеет смысла для меня.
Я добавил это в мой global.asax:
public override string GetVaryByCustomString(HttpContext context, string arg)
{
if (arg == "host")
{
return "host=" + context.Request.Url.Host;
}
return base.GetVaryByCustomString(context, arg);
}
и пример гласит "Чтобы установить пользовательскую строку программно, вызовите метод SetVaryByCustom и передайте ей пользовательскую строку для использования", с кодом, подобным следующему:
Response.Cache.SetVaryByCustom("host");
Проблема в том, что я не уверен, что с этим делать. Я добавил предыдущую строку в MvcApplication_EndRequest
потому что кажется, что это имеет смысл, но я не думаю, что это правильно, потому что, когда я устанавливаю точки останова в GetVaryByCustomString
они никогда не получают удар.
Может кто-нибудь сказать мне, что мне здесь не хватает? Или если мне нужно сделать это по-другому?
Изменить: Ответ Р. Е. Дарина ниже, я уже украшаю свои действия с:
[CustomOutputCache(CacheProfile = "FundScreener")] // or similar depending on the action
где CustomOutputCacheAttribute
определяется как:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class CustomOutputCacheAttribute: OutputCacheAttribute
{
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
AddLabelFilesDependency(filterContext);
base.OnResultExecuted(filterContext);
}
private static void AddLabelFilesDependency(ControllerContext filterContext)
{
IConfigurationManager configurationManager = ObjectFactory.TryGetInstance<IConfigurationManager>();
if (configurationManager == null
|| filterContext == null
|| filterContext.RequestContext == null
|| filterContext.RequestContext.HttpContext == null
|| filterContext.RequestContext.HttpContext.Response == null
)
{
return;
}
string[] files = Directory.GetFiles(configurationManager.LabelsDirectoryPath, "*.xml");
foreach(var file in files)
{
filterContext.RequestContext.HttpContext.Response.AddFileDependency(file);
}
}
}
где профиль определяется как:
<add name="FundScreener"
location="Server"
enabled="true"
varyByParam="*"
duration="1200"
sqlDependency="mmftms:offline.ScreenerData"/>
Мне нужно изменить это?
4 ответа
Вам не нужно звонить SetVaryByCustom
в MVC. Вы могли бы использовать OutputCache
приписывать. Оформите следующий пост в блоге.
Если вы хотите иметь разный кеш для разных хостов, вы можете использовать:
VaryByHeader = "хозяин"
Потому что это заставило бы его использовать значение заголовка "host" в запросе для изменения кэша. Вы можете добавить это в директиву OutputCache для ваших контроллеров / действий, или вы можете указать это глобально в вашем web.config, вероятно.
заголовок хоста всегда будет присутствовать, если вы используете привязки хоста, что кажется вам подходящим.
GetVaryByCustomString(...)
вызывается уровнем кэширования для каждого запроса, и у вас есть возможность проверить запрос и переданный аргумент, чтобы решить, как "классифицировать" этот запрос. Так что если вы установите VaryByCustom
свойство / атрибут для "хоста", вы бы потом написать код внутри GetVaryByCustomString
функция, которая возвращает хост (как в вашем примере выше). Если уровень кэширования обнаружит, что он уже кэшировал аргумент "host" со значением, которое вы вернули, он вернет кэшированный ответ, в противном случае он выполнит запрос и добавит его в кэш.
На основании ваших правок добавьте VaryByCustom="host"
в ваш профиль выходного кэша FundScreener.