Удаление кэша вывода для пользовательских элементов управления в веб-формах ASP.NET

У меня есть приложение SaaS asp.net webforms, в котором работает несколько веб-сайтов электронной коммерции. Каждый веб-сайт имеет свой собственный домен (abc.com, xyz.com и т. Д.), И контент каждого веб-сайта извлекается из базы данных на основе домена.

Теперь, чтобы улучшить производительность домашней страницы, я использую кэш вывода. Обратите внимание, что домашняя страница уже содержит несколько пользовательских элементов управления (верхний колонтитул, нижний колонтитул, верхнее меню, меню пользователя, мини-тележка, баннеры, товары для дома и т. Д.). Все пользовательские элементы управления подходят для меню принятия кэша вывода (где отображаются имена пользователей, в противном случае отображаются ссылки для регистрации / входа) и мини-корзины (где отображается количество элементов корзины, и при нажатии отображается список элементов в корзине) .

Я добавил директиву кэша вывода для каждого пользовательского элемента управления (который я хочу кэшировать) с помощью VaryByCustom, чтобы создать отдельный кеш для каждого домена.

<%@ OutputCache Duration="300" VaryByParam="*" VaryByCustom="Host" %>

Поскольку VaryByHeader недоступен для UserControls, я добавил функцию переопределения в Global.asax для возврата текущего хоста.

public override string GetVaryByCustomString(HttpContext context, string arg)
{
    if (arg == "Host")
    {
        return context.Request.Url.Host;
    }

    return String.Empty;
}

До сих пор все работает идеально. Пользовательские элементы управления кэшируются для разных доменов (хостов), и срок их действия истекает в указанное время.

ПРОБЛЕМА: я хочу дать возможность в панели администратора пользователям-администраторам веб-сайтов вручную обновлять кеш своих веб-сайтов. Для этого я создал страницу (refreshcache.aspx) во внешнем приложении и просто открываю этот URL-адрес (например: abc.com/refreshcache.aspx), когда пользователи-администраторы нажимают кнопку обновления кеша на панели администратора.

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

В Home.aspx я добавил следующий код, который вызывается в Page_Load

protected void LoadControlsCache()
{
    CacheKey = "Host-" + Request.Url.Host;
    CacheKeyArray[0] = CacheKey;

    if (Cache[CacheKey] == null)
    {
        AddControlCache(header1);
        AddControlCache(footer1);
        AddControlCache(banner1);
        AddControlCache(products1);
    }
}

protected void AddControlCache(UserControl uc)
{
        StaticPartialCachingControl pcc = (StaticPartialCachingControl)uc.Parent;
        pcc.Dependency = new CacheDependency(null, CacheKeyArray);
        Cache.Insert(CacheKey, "value", null, DateTime.Now.AddSeconds(300), Cache.NoSlidingExpiration);
}

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

В refreshcache.aspx я добавил следующий код

protected void Page_Load(object sender, EventArgs e)
{
    Cache.Remove("Host-" + Request.Url.Host);
    Response.Redirect("/");
}

Я не уверен, что мне не хватает или что я делаю не так. Просто нужен способ очистить кеш пользовательского управления для определенного хоста (домена).


person Syed Ahmed    schedule 18.02.2021    source источник


Ответы (1)


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

protected void LoadControlsCache()
{
    string CacheKey = Request.Url.Host;

    AddControlCache(header1, "header-" + CacheKey);
    AddControlCache(footer1, "footer-" + CacheKey);
    AddControlCache(banner1, "banner-" + CacheKey);
    AddControlCache(products1, "products-" + CacheKey);
}

protected void AddControlCache(UserControl uc, string CacheKey)
{
    if (Cache[CacheKey] == null && uc != null)
    {
        uc.Cache.Insert(CacheKey, 1);
        uc.CachePolicy.Dependency = new System.Web.Caching.CacheDependency(null, new string[] { CacheKey });
    }
}

Затем, чтобы очистить кеш, используется Cache.Remove () со всеми ключами управления пользователем.

protected void Page_Load(object sender, EventArgs e)
{
    string CacheKey = Request.Url.Host;
    
    Cache.Remove("header-" + CacheKey);
    Cache.Remove("footer-" + CacheKey);
    Cache.Remove("banner-" + CacheKey);
    Cache.Remove("products-" + CacheKey);
    
    Response.Redirect("/");
}

Надеюсь, это поможет кому-то с подобным вопросом!

person Syed Ahmed    schedule 19.02.2021