1

キャッシュ可能性を に設定するResponse.CacheNoCache、再度変更する方法はないようです。これは、問題の簡単ですが完全な図です。

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);
}

何か不足していますか?これを行う方法はありますか?

編集:もちろん、Reflectionで設定すればうまくいきますが、あなたが設定したときに何か他のことが起こっているのではないかと心配してい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);
}
4

2 に答える 2

1

リフレクターを割って中をのぞいてみた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;
    }
}

s_cacheabilityValues静的コンストラクター中に設定されます。

s_cacheabilityValues = new int[] { -1, 0, 2, 1, 4, 3, 100 };

Dirtied()が呼び出されますが、いくつかのフラグが設定されているようです:

private void Dirtied()
{
    this._isModified = true;
    this._useCachedHeaders = false;
}

値を変更するためのルールがあるように見えますが、それほど効果があるようには見えません。そのため、おそらくリフレクションを使用して変更するだけで安全です。

fi.SetValue(Response.Cache, HttpCacheability.Private);
于 2012-09-13T21:20:42.277 に答える
0

確かに、反射が唯一の安全な方法のようです。コードをさらに詳しく見ると、以下に示すように、Response の Cache プロパティからタイプ HttpCachePolicy のオブジェクトを抽出する必要があります。

 public class HttpCachePolicyWrapper : HttpCachePolicyBase
{
    private HttpCachePolicy _httpCachePolicy;
    ....
}

そのためには、以下のコードのように、リフレクションを使用して Response.Cache オブジェクトから正しいオブジェクトの値を設定するだけです。

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

これは、ジムダネンの答えに具体的な手順を追加するだけです

于 2015-01-07T10:39:15.387 に答える