Как реализовать кэширование 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, они никогда не попадают.

Может кто-нибудь, пожалуйста, скажите мне, что мне здесь не хватает? Или если мне нужно сделать это по-другому?

Изменить: 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"/>

Нужно ли это менять?

Ответы

Ответ 1

Вам не нужно вызывать SetVaryByCustom в MVC. Вы можете использовать атрибут OutputCache. Оформить заказ после сообщения в блоге.

Ответ 2

Если вы хотите иметь различный кеш для разных хостов, вы можете использовать:

VaryByHeader = "хост"

Потому что это заставит его использовать значение заголовка "хост" в запросе для изменения кеша. Вы можете добавить это в директиву OutputCache на своих контроллерах/действиях, или вы можете указать его глобально в своем web.config, вероятно.

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

Ответ 3

GetVaryByCustomString(...) вызывается уровнем кэширования для каждого запроса, и у вас есть возможность проверить запрос и аргумент pass-in, чтобы решить, как "классифицировать" этот запрос. Поэтому, если вы устанавливаете свойство/атрибут VaryByCustom на "host", вы затем записываете код внутри функции GetVaryByCustomString, которая возвращает хост (как в вашем примере выше). Если слой кэширования обнаруживает, что он уже кэшировал аргумент "хост" со значением, которое вы вернули, он вернет кешированный ответ, иначе он выполнит запрос и добавит его в кеш.

Ответ 4

На основе вашего изменения добавьте VaryByCustom="host" в свой профиль кэша вывода FundScreener.