- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
有没有办法根据 cookie 值设置 OutputCache 的值?
为简单起见,这是我的方法
[OutputCache(Duration = 600, VaryByParam = "None", VaryByCustom = "ztest")]
public ViewResult Index()
{
return View();
}
我的 Global.asax 有这个(为了覆盖 GetVaryByCustomString 方法
public override string GetVaryByCustomString(HttpContext context, string custom)
{
if (custom == "ztest")
{
HttpCookie ztest = context.Request.Cookies["ztest"];
if (ztest != null)
{
return ztest.Value;
}
}
return base.GetVaryByCustomString(context, custom);
}
我可以验证我的浏览器是否有 ztest cookie,但是当我调试 Index 方法时,我每次都遇到断点(意味着缓存不工作)。
HttpResponse 没有出站 cookie,因此这一点不适用:https://msdn.microsoft.com/en-us/library/system.web.httpcookie.shareable(v=vs.110).aspx
If a given HttpResponse contains one or more outbound cookies with Shareable is set to false (the default value), output caching will be suppressed for the response. This prevents cookies that contain potentially sensitive information from being cached in the response and sent to multiple clients. To allow a response containing cookies to be cached, configure caching normally for the response, such as using the OutputCache directive or MVC's [OutputCache] attribute, and set all outbound cookies to have Shareable set to true.
最佳答案
微妙的答案是否定的。
解释答案如下:
输出缓存不能很好地处理 cookie 的原因
所以输出缓存不会缓存带有 cookie 的响应的原因是 cookie 可能是特定于用户的(例如身份验证、分析跟踪等)。如果一个或多个 cookie 具有 HttpCookie.Shareable = false
属性,则输出缓存认为响应不可缓存。
解决方案:
虽然有一些解决方法,输出缓存将响应 header 和内容缓存在一起,并且在将它们发送回用户之前不提供任何 Hook 来修改它们。但是,有一种方法可以提供在之前更改的能力在将响应的 header 发送回用户之前缓存响应的 header 。其中之一需要 Fasterflect nuget 包。
我有一个代码示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Caching;
using System.Web;
using System.Web.Caching;
using Fasterflect;
namespace CustomOutputCache
{
/// <summary>
/// An output cache provider that has ability to modify the http header collection before a cached response is served back to the user.
/// </summary>
public class HeaderModOutputCacheProvider : OutputCacheProvider
{
private static readonly Type OutputCacheEntryType, HttpCachePolicySettingsType;
private static readonly Type[] ParameterTypes;
public static event EventHandler<CachedRequestEventArgs> RequestServedFromCache;
static HeaderModOutputCacheProvider()
{
var systemWeb = typeof(HttpContext).Assembly;
OutputCacheEntryType = systemWeb.GetType("System.Web.Caching.OutputCacheEntry");
HttpCachePolicySettingsType = systemWeb.GetType("System.Web.HttpCachePolicySettings");
ParameterTypes = new[]{
typeof(Guid),
HttpCachePolicySettingsType,
typeof(string),
typeof(string) ,
typeof(string[]),
typeof(int),
typeof(string),
typeof(List<HeaderElement>),
typeof(List<ResponseElement>)
};
}
private readonly ObjectCache _objectCache;
public HeaderModOutputCacheProvider()
{
_objectCache = new MemoryCache("output-cache");
}
#region OutputCacheProvider implementation
public override object Get(string key)
{
var cachedValue = _objectCache.Get(key);
if (cachedValue == null)
return null;
if (cachedValue.GetType() != OutputCacheEntryType)
return cachedValue;
var cloned = CloneOutputCacheEntry(cachedValue);
if (RequestServedFromCache != null)
{
var args = new CachedRequestEventArgs(cloned.HeaderElements);
RequestServedFromCache(this, args);
}
return cloned;
}
public override object Add(string key, object entry, DateTime utcExpiry)
{
_objectCache.Set(key, entry, new CacheItemPolicy { AbsoluteExpiration = utcExpiry });
return entry;
}
public override void Set(string key, object entry, DateTime utcExpiry)
{
_objectCache.Set(key, entry, new CacheItemPolicy { AbsoluteExpiration = utcExpiry });
}
public override void Remove(string key)
{
_objectCache.Remove(key);
}
#endregion
private IOutputCacheEntry CloneOutputCacheEntry(object toClone)
{
var parameterValues = new[]
{
toClone.GetFieldValue("_cachedVaryId", Flags.InstancePrivate),
toClone.GetFieldValue("_settings", Flags.InstancePrivate),
toClone.GetFieldValue("_kernelCacheUrl", Flags.InstancePrivate),
toClone.GetFieldValue("_dependenciesKey", Flags.InstancePrivate),
toClone.GetFieldValue("_dependencies", Flags.InstancePrivate),
toClone.GetFieldValue("_statusCode", Flags.InstancePrivate),
toClone.GetFieldValue("_statusDescription", Flags.InstancePrivate),
CloneHeaders((List<HeaderElement>)toClone.GetFieldValue("_headerElements", Flags.InstancePrivate)),
toClone.GetFieldValue("_responseElements", Flags.InstancePrivate)
};
return (IOutputCacheEntry)OutputCacheEntryType.CreateInstance(
parameterTypes: ParameterTypes,
parameters: parameterValues
);
}
private List<HeaderElement> CloneHeaders(List<HeaderElement> toClone)
{
return new List<HeaderElement>(toClone);
}
}
public class CachedRequestEventArgs : EventArgs
{
public CachedRequestEventArgs(List<HeaderElement> headers)
{
Headers = headers;
}
public List<HeaderElement> Headers { get; private set; }
public void AddCookies(HttpCookieCollection cookies)
{
foreach (var cookie in cookies.AllKeys.Select(c => cookies[c]))
{
//more reflection unpleasantness :(
var header = cookie.CallMethod("GetSetCookieHeader", Flags.InstanceAnyVisibility, HttpContext.Current);
Headers.Add(new HeaderElement((string)header.GetPropertyValue("Name"), (string)header.GetPropertyValue("Value")));
}
}
}
}
这样连接:
<system.web>
<caching>
<outputCache defaultProvider="HeaderModOutputCacheProvider">
<providers>
<add name="HeaderModOutputCacheProvider" type="CustomOutputCache.HeaderModOutputCacheProvider"/>
</providers>
</outputCache>
</caching>
</system.web>
并以这种方式使用它:
HeaderModOutputCacheProvider.RequestServedFromCache += RequestServedFromCache;
HeaderModOutputCacheProvider.RequestServedFromCache += (sender, e) =>
{
e.AddCookies(new HttpCookieCollection
{
new HttpCookie("key", "value")
});
};
我不知道它是否回答了你的问题,但我希望它指出了正确的方向。
关于c# - OutputCache VaryByCustom cookie 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45988628/
我很困惑... re this和 this “元”问题... 一个非常基本的http请求: GET http://stackoverflow.com/feeds/tag?tagnames=c%23&s
protected void Page_Load(object sender, EventArgs e) {Label1.Text = DateTime.Now.ToString();} 如果在我编译
在我的应用程序中,我会记住用户在 session 中选择的语言。问题是如果我使用输出缓存,那么更改语言功能将不起作用,因为当我根据 Session["lang"] 值从数据库中检索时它会缓存结果。 那
OutputCache is an easy way to improve performance在 ASP.NET <=4.6 MVC 中。我们应该将此属性应用于非常昂贵的操作,但在第一个请求和正在
我正在使用 OutputCache 属性 [OutputCache(Duration = 3600)] 来缓存返回 View 的 Controller 。但是该 View 包含一个 Helper 方法
我在 ASP.NET 4.0 Webforms 应用程序 (IIS 7.5) 上使用一个非常简单的输出缓存指令,该指令将页面缓存 1 小时。该应用程序没有任何内存压力,但页面在一小时之前就过期了。我创
我的 Controller 方法有以下缓存属性: [CacheOutput(ClientTimeSpan = 14400, ServerTimeSpan = 14400)] 我正在尝试清除缓存。然而
我在 ASP.net MVC 应用程序中使用 OutputCache。由于使用事件的 OutputCache 进行开发并不是很愉快,因此我想禁用开发系统(本地计算机和开发服务器)上的 OutputCa
我是一个为应用程序创建菜单的部分页面。我正在使用 renderaction 调用菜单部分 View 。我想通过这样做将这个部分页面存储在客户端 [OutputCache(Duration=7200,
我在某处读到,对于高流量站点(我想这也是一个模糊的术语),30 - 60 秒是一个不错的值。显然我可以进行负载测试并改变值,但我找不到任何类型的文档。大多数样本只有一分钟,几分钟。没有推荐范围。 ms
我正在尝试在我的 MVC 应用程序中使用 OutputCache 属性,但当我使用 OutputCacheLocation.Client 时它似乎不起作用: public class HomeCont
我在 MVC 5 中使用 OutputCache 来缓存服务器上的 View 。 我只想根据查询字符串中的两个参数缓存一个 View 。 操作方法 [HttpGet] [OutputCache(Loc
我遇到了一些奇怪的缓存问题,并将一个非常简单的 .NET 页面与输出缓存指令放在一起。但是,页面没有缓存(每次刷新时内容都会更新)。 我在我的本地机器(Windows 7)上安装了一个简单的、最小的
有人可以帮助解释什么是 OutputCache VaryByContentEncoding 的用途,或者更好地举例说明其用法。 我知道这与编码压缩有关。它会根据特定的压缩方案缓存不同的响应吗?我在网上
如果我将以下内容添加到我的应用程序/ Controller [OutputCache(Duration = 7200)] 我在网站上有两个用户,User1 和 User2。如果User1浏览到打开上述
假设我有一个页面请求,如下所示 http://localhost/accounting/products?id=234 有时它是这样的: http://localhost/accounting/pro
我能够正确利用 ASP.NET MVC4 OutputCache,并将以下代码作为我的 Controller Index() 上的属性: [OutputCache(Duration = 600, Va
对于我当前的项目,有必要生成动态 CSS... 所以,我有一个充当 CSS 交付者的部分 View ... Controller 代码如下所示: [OutputCache(CacheProfi
我不确定是什么原因造成的,但我们的 Controller 操作用于缓存其输出,但现在不再这样做了: [HttpGet] [OutputCache(VaryByParam = "slug", Durat
是否可以迭代 OutputCache 键?我知道您可以通过 HttpResponse.RemoveOutputCacheItem() 单独删除它们,但是有没有一种方法可以迭代所有键以查看集合中的内容?
我是一名优秀的程序员,十分优秀!