C# 更改Response.Cache.\u将其设置为NoCache后的可缓存性
似乎一旦将C# 更改Response.Cache.\u将其设置为NoCache后的可缓存性,c#,asp.net,caching,C#,Asp.net,Caching,似乎一旦将Response.Cache上的可缓存性设置为NoCache,就无法再次更改它。以下是一个简单但完整的问题说明: protected void Page_Load(object sender, EventArgs e) { FieldInfo fi = typeof(HttpCachePolicy).GetField( "_cacheability", BindingFlags.NonPublic | BindingFlags.Instance)
Response.Cache
上的可缓存性设置为NoCache
,就无法再次更改它。以下是一个简单但完整的问题说明:
protected void Page_Load(object sender, EventArgs e)
{
FieldInfo fi = typeof(HttpCachePolicy).GetField(
"_cacheability",
BindingFlags.NonPublic | BindingFlags.Instance);
// Default value = 6
HttpCacheability first = (HttpCacheability)fi.GetValue(Response.Cache);
// Can change it to Public
Response.Cache.SetCacheability(HttpCacheability.Public);
HttpCacheability second = (HttpCacheability)fi.GetValue(Response.Cache);
// Can change it to Private
Response.Cache.SetCacheability(HttpCacheability.Private);
HttpCacheability third = (HttpCacheability)fi.GetValue(Response.Cache);
// Can change it to NoCache
Response.Cache.SetCacheability(HttpCacheability.NoCache);
HttpCacheability fourth = (HttpCacheability)fi.GetValue(Response.Cache);
// Can't go back to Private! Stuck on NoCache
Response.Cache.SetCacheability(HttpCacheability.Private);
HttpCacheability fifth = (HttpCacheability)fi.GetValue(Response.Cache);
}
我错过什么了吗?有办法做到这一点吗
编辑:当然,如果我将其设置为反射,它会起作用,但我担心当您设置为HttpCacheability.NoCache时会发生其他事情,如果我在幕后,我会错过这些事情。。而且更愿意以官方支持的方式进行
EDIT2:同样的事情似乎发生在Private
;你能不能更严格一点
protected void Page_Load(object sender, EventArgs e)
{
FieldInfo fi = typeof(HttpCachePolicy).GetField(
"_cacheability",
BindingFlags.NonPublic | BindingFlags.Instance);
// Default value = 6
HttpCacheability first = (HttpCacheability)fi.GetValue(Response.Cache);
// Can change it to Private
Response.Cache.SetCacheability(HttpCacheability.Private);
HttpCacheability second = (HttpCacheability)fi.GetValue(Response.Cache);
// Can't change to Public! Stuck on Private
Response.Cache.SetCacheability(HttpCacheability.Public);
HttpCacheability third = (HttpCacheability)fi.GetValue(Response.Cache);
// Can change to NoCache - Can only go more restrictive?
Response.Cache.SetCacheability(HttpCacheability.NoCache);
HttpCacheability fourth = (HttpCacheability)fi.GetValue(Response.Cache);
}
打开反射器并查看内部HttpCachePolicy
:
public void SetCacheability(HttpCacheability cacheability)
{
if ((cacheability < HttpCacheability.NoCache) || (HttpCacheability.ServerAndPrivate < cacheability))
{
throw new ArgumentOutOfRangeException("cacheability");
}
if (s_cacheabilityValues[(int) cacheability] < s_cacheabilityValues[(int) this._cacheability])
{
this.Dirtied();
this._cacheability = cacheability;
}
}
调用了dirtie()
,但它似乎只是设置了一些标志:
private void Dirtied()
{
this._isModified = true;
this._useCachedHeaders = false;
}
看起来确实有更改值的规则,但似乎没有多大影响。因此,使用反射进行更改可能是安全的
fi.SetValue(Response.Cache, HttpCacheability.Private);
打开反射器并查看内部HttpCachePolicy
:
public void SetCacheability(HttpCacheability cacheability)
{
if ((cacheability < HttpCacheability.NoCache) || (HttpCacheability.ServerAndPrivate < cacheability))
{
throw new ArgumentOutOfRangeException("cacheability");
}
if (s_cacheabilityValues[(int) cacheability] < s_cacheabilityValues[(int) this._cacheability])
{
this.Dirtied();
this._cacheability = cacheability;
}
}
调用了dirtie()
,但它似乎只是设置了一些标志:
private void Dirtied()
{
this._isModified = true;
this._useCachedHeaders = false;
}
看起来确实有更改值的规则,但似乎没有多大影响。因此,使用反射进行更改可能是安全的
fi.SetValue(Response.Cache, HttpCacheability.Private);
事实上,反思似乎是唯一安全的方法。深入查看代码,您需要从响应的Cache属性中提取HttpCachePolicy类型的对象,如下所示:
public class HttpCachePolicyWrapper : HttpCachePolicyBase
{
private HttpCachePolicy _httpCachePolicy;
....
}
为此,只需使用反射设置响应中正确对象的值。缓存对象,如以下代码所示:
FieldInfo fi = typeof(HttpCachePolicy).GetField("_cacheability", BindingFlags.NonPublic | BindingFlags.Instance);
var objectToChange = (HttpCachePolicy)context.Response.Cache.GetType().GetField("_httpCachePolicy", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(context.Response.Cache);
fi.SetValue(objectToChange, HttpCacheability.Public);
这只是给津巴布韦人的答案增加了更多的复杂步骤事实上,反射似乎是唯一安全的方法。深入查看代码,您需要从响应的Cache属性中提取HttpCachePolicy类型的对象,如下所示:
public class HttpCachePolicyWrapper : HttpCachePolicyBase
{
private HttpCachePolicy _httpCachePolicy;
....
}
为此,只需使用反射设置响应中正确对象的值。缓存对象,如以下代码所示:
FieldInfo fi = typeof(HttpCachePolicy).GetField("_cacheability", BindingFlags.NonPublic | BindingFlags.Instance);
var objectToChange = (HttpCachePolicy)context.Response.Cache.GetType().GetField("_httpCachePolicy", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(context.Response.Cache);
fi.SetValue(objectToChange, HttpCacheability.Public);
这只是给zimdanen的答案增加了更多的复杂步骤现在回想起来,可能想同时将\u useCachedHeaders
设置为false,或者使用反射调用dirtie()
。现在回想起来,可能想同时将\u useCachedHeaders
设置为false,或者使用反射调用dirtie()
。