Ответ 1
Вам не нужно вызывать SetVaryByCustom
в MVC. Вы можете использовать атрибут OutputCache
. Оформить заказ после сообщения в блоге.
Я пытаюсь реализовать функции кэширования определенных страниц в зависимости от хоста. Это связано с тем, что я могу иметь несколько версий страницы, которые имеют одинаковые параметры, и где единственная разница в терминах запроса - это хост, который запрашивается.
Итак, например, эти два 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
, они никогда не попадают.
Может кто-нибудь, пожалуйста, скажите мне, что мне здесь не хватает? Или если мне нужно сделать это по-другому?
Изменить: RE Дарин ответ ниже, я уже украшаю свои действия:
[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"/>
Нужно ли это менять?
Вам не нужно вызывать SetVaryByCustom
в MVC. Вы можете использовать атрибут OutputCache
. Оформить заказ после сообщения в блоге.
Если вы хотите иметь различный кеш для разных хостов, вы можете использовать:
VaryByHeader = "хост"
Потому что это заставит его использовать значение заголовка "хост" в запросе для изменения кеша. Вы можете добавить это в директиву OutputCache на своих контроллерах/действиях, или вы можете указать его глобально в своем web.config, вероятно.
заголовок хоста всегда будет присутствовать, если вы используете привязки хостов, что, кажется, относится к вам.
GetVaryByCustomString(...)
вызывается уровнем кэширования для каждого запроса, и у вас есть возможность проверить запрос и аргумент pass-in, чтобы решить, как "классифицировать" этот запрос. Поэтому, если вы устанавливаете свойство/атрибут VaryByCustom
на "host", вы затем записываете код внутри функции GetVaryByCustomString
, которая возвращает хост (как в вашем примере выше). Если слой кэширования обнаруживает, что он уже кэшировал аргумент "хост" со значением, которое вы вернули, он вернет кешированный ответ, иначе он выполнит запрос и добавит его в кеш.
На основе вашего изменения добавьте VaryByCustom="host"
в свой профиль кэша вывода FundScreener.