10

ASP.NET MVC 2では、のエントリの有効期間はTempDataDictionary1つのHTTP要求のみでした。

これは、1つのリクエストに値を設定し、リダイレクトし、行のもう一方の端にある同じアイテムにアクセスできるようにすることを意味します。この後、行の最後にあるディクショナリから値を読み取るかどうかに関係なく、エントリは使用できなくなります。

ASP.NET MVC 3(私は信じています)以来、この実装の詳細はかなり大幅に変更されました。

のエントリは、TempDataDictionary読み取られた後にのみ削除されるようになりました。

MVC 4

public object this[string key]
    {
      get
      {
        object obj;
        if (!this.TryGetValue(key, out obj))
          return (object) null;
        this._initialKeys.Remove(key);
        return obj;
      }
    }

public bool TryGetValue(string key, out object value)
    {
      this._initialKeys.Remove(key);
      return this._data.TryGetValue(key, out value);
    }

MVC 2:

public object this[string key] {
            get {
                object value;
                if (TryGetValue(key, out value)) {
                    return value;
                }
                return null;
            }

public bool TryGetValue(string key, out object value) {
            return _data.TryGetValue(key, out value);
        }

ほとんどの人はTempData、1つのリクエストでアイテムをコレクションに入れ、すぐに次のリクエストでそれらを読み戻すように見えるため、機能はほぼ同じように見えます。

TempDataある場所にリダイレクトされた場合にエントリを読み取りたい場合や、他のリソースを要求して戻った場合にエントリが削除されることを期待する場合など、これが当てはまらないシナリオでは、この変更は大きな影響を及ぼします。

1つのhttpリクエストで使用できるエントリはなくなりましたが、ディクショナリの1つのgetでのみ使用できるため、多くのHTTPリクエストで使用できます。

この含意の変更についてもっと知りたいのですが、変更の理由は何でしたか、これは単に複数のリダイレクトに対応するためでしたか、それともより深いメリットがありますか?

TempDataそれに続いて、以前と同じ方法でデータの単一のHTTPリクエスト共有に対応するものが組み込まれているのかどうか知りたいと思っています。

4

1 に答える 1

6

You're correct that TempData keys are only cleared if they’ve been read (or after the user’s session expires) but this has been the case since MVC2, (http://forums.asp.net/post/3692286.aspx)

I'd like to know more about this implimentation change, what were the reasons for the change, was this simply to cater for multiple redirects or are there deeper benefits?

This change prevented problems that arose in MVC 1, such as TempData keys being deleted before they were read. So yes, the primary benefit is in avoiding these problems when you have multiple re-directs, or interleaved requests. In addition, the RedirectToRouteResult or RedirectResult methods now automatically call TempData.Keep() to prevent clearing of keys, even after they've been read so keep that in mind as well.

In scenarios where this is not the case such as wanting to read the TempData entry if redirected to one place, and expecting it to have been removed if requesting other resources and navigating back, this change has quite an impact.

You’re correct, if you've been coding under the assumption that the TempData keys are cleared automatically you could run into unexpected problems. You can call TempData.Clear() to manually remove all keys from the TempDataDictionary, or TempData.Remove(key) to remove a specific key. You can also use TempData.Peek() to read the value of a TempData key without flagging it for removal from the TempDataDictionary.

Secondary to that, I'm intrigued to know if there's anything built in that now caters for single HTTP request sharing of data in the same way that TempData used to cater for?

I'm not aware of any new objects or functions that replicate the original implementation of TempData. Essentially we still use TempData but have to be mindful that the data persists until read and clear the dictionary manually if needed.

于 2013-02-19T20:48:46.373 に答える