【问题标题】:Output cache code behind for non session users为非会话用户输出缓存代码
【发布时间】:2016-11-30 22:22:48
【问题描述】:

如果 Session["user"] 是否为空,我是否可以在可以在代码中检测到的页面中进行输出缓存,如果页面尚未缓存(输出缓存未过期),则将页面缓存 5 分钟,并且Session["user"] == null。

我不想使用自定义输出缓存,因为它也会为登录用户缓存。这样,只有匿名访问者会看到缓存的页面,而登录的用户会看到未缓存的页面

我这样做是因为当用户登录或未登录时,我的某些页面看起来会有所不同。我希望爬虫和普通访问者看到原始页面,而不是从错误触发缓存的用户那里获取私有数据。

如何在 C# 后面的代码中做到这一点?

【问题讨论】:

标签: c# asp.net c#-4.0 outputcache


【解决方案1】:

您应该能够创建自定义OutputCacheProvider

在您的 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.
    }
}

通过从Set 返回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/的代码

注意,我没有用 Session 测试过这个,但理论上它应该可以工作。但是我建议您在发布之前对其进行真正的测试。缓存总是比人们想象的要困难得多... :(

更新:由于 Session 不可用,您应该可以使用 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,或以某种方式处理它。

【讨论】:

  • 谢谢。我应该在页面中添加什么以使此自定义输出缓存正常工作?
  • 如果我使用第二个代码(“相同的 CacheProvider”),我可以从 web.config 中删除更改吗?
  • 我已经更新了我的答案。但是你仍然需要在 web.config 中注册它。否则 .NET 将无法按名称找到您的提供程序。请注意,注册为&lt;add name="foo"...的名称很重要。
  • 我是否应该在页面中使用此代码:""
  • 位置是缓存的存储位置。例如。服务器,客户端。我在回答中添加了对它的引用。而且您不需要任何 VaryByParam,因为它是由提供者处理的。
猜你喜欢
  • 2015-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多