Код кэша вывода для пользователей, не являющихся сеансами

Могу ли я выполнить кэширование вывода на страницах, которые я могу обнаружить в коде позади, если Session ["user"] имеет значение NULL или нет, и кэшировать страницу в течение 5 минут, если она еще не кэширована (срок кеширования вывода не истек) и Session [ "пользователь"] == null.

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

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

Как я могу сделать это в коде на C #?


person Idan Shechter    schedule 27.07.2016    source источник
comment
Вы должны уметь использовать GetVaryByCustomString. Взгляните на эти blog.danielcorreia.net/asp- net-mvc-change-by-current-user stackoverflow.com/questions/1043112/   -  person smoksnes    schedule 27.07.2016
comment
@smoksnes, но это создаст кеш для каждого пользователя, верно?   -  person Idan Shechter    schedule 27.07.2016
comment
Да, ты прав. Виноват.   -  person smoksnes    schedule 27.07.2016


Ответы (1)


У вас должна быть возможность создать собственный _ 1_.

В вашем global.asax:

    public override string GetOutputCacheProviderName(HttpContext context)
    {
        bool isInSession = true; // Determine here.
        if (isInSession)
        {
            return "CustomProvider";
        }

        // Or by page:
        if (context.Request.Path.EndsWith("MyPage.aspx"))
        {
            return "SomeOtherProvider";
        }

        return base.GetOutputCacheProviderName(context);
    }

Затем создайте своего провайдера:

public class SessionBasedCacheProvider : OutputCacheProvider
{
    public override object Get(string key)
    {
        return null; // Do not cache.
    }

    public override object Add(string key, object entry, DateTime utcExpiry)
    {
        // Basically let it "fall through" since we don't want any caching.
        return entry;
    }

    public override void Set(string key, object entry, DateTime utcExpiry)
    {
        // Basically let it "fall through" since we don't want any caching.            
    }

    public override void Remove(string key)
    {
        // Basically let it "fall through" since we don't want any caching.
    }
}

Вернув null из Установите, вы не будете кэшировать элементы.

Значение ключа, которое идентифицирует указанную запись в кэше, или null, если указанная запись отсутствует в кэше.

И добавляем в конфиг своего провайдера:

  <system.web>
    <caching>
      <outputCache defaultProvider="AspNetInternalProvider">
        <providers>
          <clear/>
          <add name="CustomProvider" type="YourNamespace.SessionBasedCacheProvider, YourNamespace, Version=1.0.0.0, Culture=neutral"/>
        </providers>
      </outputCache>
    </caching>
</web>

Чтобы включить его, вы должны уметь использовать. Просто установите это в начало страницы ASPX. Обратите внимание на атрибут Location, в зависимости от того, где вы хотите его кэшировать.

<%@ OutputCache Duration="60" VaryByParam="None" Location="Server"  %>

https://msdn.microsoft.com/en-us/library/hdxfb6cy(v=vs.85).aspx

https://msdn.microsoft.com/en-us/magazine/gg650661.aspx

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

public class CustomOutputCacheProvider : OutputCacheProvider
{
    public override object Add(string key, object entry, DateTime utcExpiry)
    {
        // Determine if in session.
        bool isInSession = true;
        if (isInSession)
        {
            return null;
        }

        // Do the same custom caching as you did in your 
        // CustomMemoryCache object
        var result = HttpContext.Current.Cache.Get(key);

        if (result != null)
        {
            return result;
        }

        HttpContext.Current.Cache.Add(key, entry, null, utcExpiry,
            System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal, null);

        return entry;
    }

    public override object Get(string key)
    {
        return HttpContext.Current.Cache.Get(key);
    }

    public override void Remove(string key)
    {
        HttpContext.Current.Cache.Remove(key);
    }

    public override void Set(string key, object entry, DateTime utcExpiry)
    {
        HttpContext.Current.Cache.Add(key, entry, null, utcExpiry,
            System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal, null);
    }
}

Код из http://www.haneycodes.net/custom-output-caching-with-mvc3-and-net-4-0-done-right/

Обратите внимание: я не тестировал это с помощью сеанса, но теоретически это должно работать. Но я предлагаю вам действительно протестировать его, прежде чем выпускать его. Кеширование всегда намного сложнее, чем можно было подумать ... :(

ОБНОВЛЕНИЕ: поскольку сеанс недоступен, вы можете использовать вместо него файл cookie.

protected void Session_Start(object sender, EventArgs e)
{
    Response.Cookies.Add(new HttpCookie("SessionCookie", "some_value"));
}

public override string GetOutputCacheProviderName(HttpContext context)
{
    bool isInSession = true; // Determine here.

    if (context.Request.Cookies["SessionCookie"] != null)
    {
        // Use your CustomProvider
    }

    if (isInSession)
    {
        return "CustomProvider";
    }

    // Or by page:
    if (context.Request.Path.EndsWith("MyPage.aspx"))
    {
        return "SomeOtherProvider";
    }

    return base.GetOutputCacheProviderName(context);
}

Просто не забудьте удалить файл cookie или обработать его каким-либо образом.

person smoksnes    schedule 27.07.2016
comment
Спасибо. Что мне добавить на страницу, на которой я хочу, чтобы этот настраиваемый выходной кеш работал? - person Idan Shechter; 27.07.2016
comment
Если я использую второй код (тот же CacheProvider,), я могу удалить измененный из web.config? - person Idan Shechter; 27.07.2016
comment
Я обновил свой ответ. Но вам все равно нужно зарегистрировать его в web.config. В противном случае .NET не найдет вашего провайдера по имени. Обратите внимание, что это имя, зарегистрированное как <add name="foo"..., важно. - person smoksnes; 27.07.2016
comment
Следует ли мне использовать этот код на странице: ‹% @ OutputCache Duration = 60 Location = CustomPRovider VaryByParam = name%› - person Idan Shechter; 27.07.2016
comment
Местоположение - это место, где хранится кеш. Например. Сервер, Клиент. Я добавил ссылку на него в своем ответе. И вам не нужен VaryByParam, поскольку он обрабатывается провайдером. - person smoksnes; 27.07.2016
comment
так что это должно быть: VaryByCustom = CustomProvider - person Idan Shechter; 27.07.2016
comment
Я не думаю, что вам нужен VaryBy, так как CustomProvider позаботится об этом. VaryBy используется, чтобы помочь определить, какие страницы разные. Но в вашем случае этим занимается CustomProvider. И установив GetOutputCacheProviderName в global.asax, вы определите вместо этого. - person smoksnes; 27.07.2016
comment
context.Session имеет значение null, хотя пользователь вошел в систему Session [user] = 5 - person Idan Shechter; 27.07.2016
comment
если (контекст! = ноль && context.Session! = ноль) {isInSession = true; } - person Idan Shechter; 27.07.2016
comment
Позвольте нам продолжить это обсуждение в чате. - person smoksnes; 27.07.2016