C# 浏览器缓存是否可以通过代码清除?
我的网站上有一个菜单,根据用户是否登录而变化。使用浏览器缓存时,菜单在任何一种状态下都会“卡住”,用户会感到困惑 他们将登录,但菜单不会更新,因为它仍缓存在未经验证的状态。。。反之亦然 这通常是如何处理的?我们可以从代码中刷新用户的浏览器缓存吗?或者我只是不允许浏览器缓存?(宁愿使用它,在速度上有很好的颠簸) 更新 下面是我在asp.net mvc 2应用程序中设置客户端浏览器缓存的方法:C# 浏览器缓存是否可以通过代码清除?,c#,asp.net,browser,caching,C#,Asp.net,Browser,Caching,我的网站上有一个菜单,根据用户是否登录而变化。使用浏览器缓存时,菜单在任何一种状态下都会“卡住”,用户会感到困惑 他们将登录,但菜单不会更新,因为它仍缓存在未经验证的状态。。。反之亦然 这通常是如何处理的?我们可以从代码中刷新用户的浏览器缓存吗?或者我只是不允许浏览器缓存?(宁愿使用它,在速度上有很好的颠簸) 更新 下面是我在asp.net mvc 2应用程序中设置客户端浏览器缓存的方法: public class CacheFilterAttribute : ActionFilterAttri
public class CacheFilterAttribute : ActionFilterAttribute {
/// <summary>
/// Gets or sets the cache duration in seconds. The default is 10 seconds.
/// </summary>
/// <value>The cache duration in seconds.</value>
public int Duration { get; set; }
public CacheFilterAttribute() { Duration = 10; }
public override void OnActionExecuted(ActionExecutedContext filterContext) {
if (Duration <= 0) return;
var cache = filterContext.HttpContext.Response.Cache;
var cacheDuration = TimeSpan.FromSeconds(Duration);
cache.SetCacheability(HttpCacheability.Public);
cache.SetExpires(DateTime.Now.Add(cacheDuration));
cache.SetMaxAge(cacheDuration);
cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
}
}
公共类CacheFilterAttribute:ActionFilterAttribute{
///
///获取或设置缓存持续时间(秒)。默认值为10秒。
///
///缓存持续时间(秒)。
公共整数持续时间{get;set;}
公共CacheFilterAttribute(){Duration=10;}
公共覆盖无效OnActionExecuted(ActionExecutedContext筛选器上下文){
如果(Duration您可能想尝试甜甜圈洞缓存并缓存除菜单之外的所有内容。Scott Guthrie在该主题上有一个不错的方法。您可能想尝试甜甜圈洞缓存并缓存除菜单之外的所有内容。Scott Guthrie在该主题上有一个不错的方法。我一直在使用一个动作过滤器来模拟这种行为有条件的请求和电子标签,这是纯客户端缓存,因此这里不涉及输出缓存。您仍然会收到服务器的请求,但不会调用该操作,如果本地缓存仍然是新的,客户端将使用本地缓存
/// <summary>
/// Handles client side caching by automatically refreshing content when switching logged in identity
/// </summary>
public class ClientCacheByIdentityAttribute : ActionFilterAttribute
{
/// <summary>
/// Sets the cache duraction in minutes
/// </summary>
public int Duration { get; set; }
/// <summary>
/// Check for incoming conditional requests
/// </summary>
/// <param name="filterContext"></param>
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.IsChildAction || filterContext.HttpContext.Request.RequestType!="GET" || filterContext.Result!=null)
{
return;
}
string modifiedSinceString = filterContext.HttpContext.Request.Headers["If-Modified-Since"];
string noneMatchString = filterContext.HttpContext.Request.Headers["If-None-Match"];
if (String.IsNullOrEmpty(modifiedSinceString) || String.IsNullOrEmpty(noneMatchString))
{
return;
}
DateTime modifiedSince;
if (!DateTime.TryParse(modifiedSinceString, out modifiedSince))
{
return;
}
if (modifiedSince.AddMinutes(Duration) < DateTime.Now)
{
return;
}
string etag = CreateETag(filterContext.HttpContext);
if (etag == noneMatchString)
{
filterContext.HttpContext.Response.StatusCode = 304;
filterContext.Result = new EmptyResult();
}
}
/// <summary>
/// Handles setting the caching attributes required for conditional gets
/// </summary>
/// <param name="filterContext"></param>
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.HttpContext.Request.RequestType == "GET" && filterContext.HttpContext.Response.StatusCode == 200 && !filterContext.IsChildAction && !filterContext.HttpContext.Response.IsRequestBeingRedirected)
{
filterContext.HttpContext.Response.AddHeader("Last-Modified", DateTime.Now.ToString("r"));
filterContext.HttpContext.Response.AddHeader("ETag", CreateETag(filterContext.HttpContext));
}
}
/// <summary>
/// Construct the ETag
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
private static string CreateETag(HttpContextBase context)
{
return "\"" + CalculateMD5Hash(context.Request.Url.PathAndQuery + "$" + context.User.Identity.Name) + "\"";
}
/// <summary>
/// Helper to make an MD5 hash
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private static string CalculateMD5Hash(string input)
{
MD5 md5 = MD5.Create();
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
byte[] hash = md5.ComputeHash(inputBytes);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("X2"));
}
return sb.ToString();
}
}
//
///通过在切换登录标识时自动刷新内容来处理客户端缓存
///
公共类ClientCacheByIdentityAttribute:ActionFilterAttribute
{
///
///以分钟为单位设置缓存持续时间
///
公共整数持续时间{get;set;}
///
///检查传入的条件请求
///
///
公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
{
if(filterContext.IsChildAction | | filterContext.HttpContext.Request.RequestType!=“GET”| | filterContext.Result!=null)
{
返回;
}
string ModifiedSe伦=filterContext.HttpContext.Request.Headers[“如果自”]起修改);
string noneMatchString=filterContext.HttpContext.Request.Headers[“如果不匹配”];
if(String.IsNullOrEmpty(modifiedscentering)| | String.IsNullOrEmpty(noneMatchString))
{
返回;
}
日期时间修改自;
if(!DateTime.TryParse(modifiedSequeString,out modifiedSince))
{
返回;
}
如果(修改了ince.AddMinutes(持续时间)
我一直在使用一个动作过滤器,使用条件请求和电子标签模拟这种行为,这是纯客户端缓存,因此这里不涉及输出缓存。您仍然会收到服务器的请求,但不会调用动作,如果本地缓存仍然新鲜,客户端将使用本地缓存
/// <summary>
/// Handles client side caching by automatically refreshing content when switching logged in identity
/// </summary>
public class ClientCacheByIdentityAttribute : ActionFilterAttribute
{
/// <summary>
/// Sets the cache duraction in minutes
/// </summary>
public int Duration { get; set; }
/// <summary>
/// Check for incoming conditional requests
/// </summary>
/// <param name="filterContext"></param>
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.IsChildAction || filterContext.HttpContext.Request.RequestType!="GET" || filterContext.Result!=null)
{
return;
}
string modifiedSinceString = filterContext.HttpContext.Request.Headers["If-Modified-Since"];
string noneMatchString = filterContext.HttpContext.Request.Headers["If-None-Match"];
if (String.IsNullOrEmpty(modifiedSinceString) || String.IsNullOrEmpty(noneMatchString))
{
return;
}
DateTime modifiedSince;
if (!DateTime.TryParse(modifiedSinceString, out modifiedSince))
{
return;
}
if (modifiedSince.AddMinutes(Duration) < DateTime.Now)
{
return;
}
string etag = CreateETag(filterContext.HttpContext);
if (etag == noneMatchString)
{
filterContext.HttpContext.Response.StatusCode = 304;
filterContext.Result = new EmptyResult();
}
}
/// <summary>
/// Handles setting the caching attributes required for conditional gets
/// </summary>
/// <param name="filterContext"></param>
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.HttpContext.Request.RequestType == "GET" && filterContext.HttpContext.Response.StatusCode == 200 && !filterContext.IsChildAction && !filterContext.HttpContext.Response.IsRequestBeingRedirected)
{
filterContext.HttpContext.Response.AddHeader("Last-Modified", DateTime.Now.ToString("r"));
filterContext.HttpContext.Response.AddHeader("ETag", CreateETag(filterContext.HttpContext));
}
}
/// <summary>
/// Construct the ETag
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
private static string CreateETag(HttpContextBase context)
{
return "\"" + CalculateMD5Hash(context.Request.Url.PathAndQuery + "$" + context.User.Identity.Name) + "\"";
}
/// <summary>
/// Helper to make an MD5 hash
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private static string CalculateMD5Hash(string input)
{
MD5 md5 = MD5.Create();
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
byte[] hash = md5.ComputeHash(inputBytes);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("X2"));
}
return sb.ToString();
}
}
//
///通过在切换登录标识时自动刷新内容来处理客户端缓存
///
公共类ClientCacheByIdentityAttribute:ActionFilterAttribute
{
///
///以分钟为单位设置缓存持续时间
///
公共整数持续时间{get;set;}
///
///检查传入的条件请求
///
///
公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
{
if(filterContext.IsChildAction | | filterContext.HttpContext.Request.RequestType!=“GET”| | filterContext.Result!=null)
{
返回;
}
string ModifiedSe伦=filterContext.HttpContext.Request.Headers[“如果自”]起修改);
string noneMatchString=filterContext.HttpContext.Request.Headers[“如果不匹配”];
if(String.IsNullOrEmpty(modifiedscentering)| | String.IsNullOrEmpty(noneMatchString))
{
返回;
}
日期时间修改自;
if(!DateTime.TryParse(modifiedSequeString,out modifiedSince))
{
返回;
}
如果(修改了ince.AddMinutes(持续时间)