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

Другие вопросы по тегам