Как реализовать кэширование VaryByCustom? - PullRequest
15 голосов
/ 15 марта 2011

Я пытаюсь реализовать функциональность для кэширования определенных страниц в зависимости от хоста.Это потому, что у меня может быть несколько версий страницы, которые имеют одинаковые параметры, и где единственное различие в терминах запроса - запрашиваемый хост.

Так, например, эти два 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"/>

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

Ответы [ 4 ]

7 голосов
/ 15 марта 2011

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

4 голосов
/ 15 марта 2011

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

VaryByHeader = "host"

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

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

3 голосов
/ 15 марта 2011

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

0 голосов
/ 15 марта 2011

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

...