Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/30.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 更改Response.Cache.\u将其设置为NoCache后的可缓存性_C#_Asp.net_Caching - Fatal编程技术网

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()