如何在ASP.NETMVC中为经过身份验证的用户关闭输出缓存?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (21)

我有一个ASP.NET MVC应用程序。我需要缓存一些页面,但仅限于未经过身份验证的用户。

我试过用VaryByCustom="user"下面的GetVaryByCustomString实现:

public override string GetVaryByCustomString(HttpContext context, string custom)
{
  if (custom == "user")
  {
      if (context.User.Identity.IsAuthenticated)
      {
        return context.User.Identity.Name;
      }
      else
      {
        return "";
      }
  }  

  return base.GetVaryByCustomString(context, custom);
}

然而这并不是我所需要的,因为页面仍然被缓存。唯一的区别是,现在分别为每个用户缓存。

一种可能的解决方案是Guid.NewGuid()每次用户进行身份验证时返回,但看起来像是对我的巨大资源浪费。

那么你对我有什么建议吗?

提问于
用户回答回答于

所以这就是我所做的:

public class NonAuthenticatedOnlyCacheAttribute : OutputCacheAttribute
{
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
      var httpContext = filterContext.HttpContext;

      if (httpContext.User.Identity.IsAuthenticated)
      {
        // it's crucial not to cache Authenticated content
        Location = OutputCacheLocation.None;
      }

      // this smells a little but it works
      httpContext.Response.Cache.AddValidationCallback(IgnoreAuthenticated, null);

      base.OnResultExecuting(filterContext);
    }

    // This method is called each time when cached page is going to be
    // served and ensures that cache is ignored for authenticated users.
    private void IgnoreAuthenticated(HttpContext context, object data, ref HttpValidationStatus validationStatus)
    {
      if (context.User.Identity.IsAuthenticated)            
        validationStatus = HttpValidationStatus.IgnoreThisRequest;          
      else          
        validationStatus = HttpValidationStatus.Valid;          
    }
}
用户回答回答于

一般情况下属性都被缓存,那么你需要存储原始位置。如果访问Logged页面,它将Location设置为None,那么当以匿名方式访问时,它仍然是None。

public class AuthenticatedOnServerCacheAttribute : OutputCacheAttribute
{
    private OutputCacheLocation? originalLocation;

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        var httpContext = filterContext.HttpContext;

        if (httpContext.User.Identity.IsAuthenticated)
        {
            originalLocation = originalLocation ?? Location;
            Location = OutputCacheLocation.None;
        }
        else
        {
            Location = originalLocation ?? Location;
        }

        base.OnResultExecuting(filterContext);
    }
}

扫码关注云+社区