web-dev-qa-db-ja.com

ASP.Net MVCでTempData対Sessionを使用する場合

私はMVCフレームワークのコツをつかもうとしているので、我慢してください。

現在、セッションストアを使用しているのは、現在ログインしているユーザーを保存することだけです。私のウェブサイトはシンプルです。この例では、Person、Meeting、およびFileの3つのドメインオブジェクトを検討します。ユーザーは、ログインして会議の「メンバーのみ」プロファイルを表示し、ファイルを追加できます。ログインしていない場合は、会議の公開「プロファイル」を表示できます。

そのため、ログインしているユーザーの会議のプライベートプロファイルから、「ファイルの追加」リンクがあります。このリンクはFileContoller.Add(int meetingId)にルーティングされます。このアクションから、ユーザーが会議IDを使用してファイルを追加する会議を取得しますが、フォームが投稿された後、ユーザーがどの会議にファイルを追加しているかを知る必要があります。そこで質問があります。「現在やり取りしている」会議をTempData経由で渡すか、セッションストアに追加する必要がありますか。

これは私が現在追加アクション設定を持っている方法ですが、機能していません:

    public ActionResult Add(int meetingId)
    {
        try
        {
            var meeting = _meetingsRepository.GetById(meetingId);
            ViewData.Model = meeting;
            TempData[TempDataKeys.CurrentMeeting] = meeting; /* add to tempdata here */
        }
        catch (Exception)
        {
            TempData[TempDataKeys.ErrorMessage] = "Unable to add files to this meeting.";
            return RedirectToRoute("MeetingsIndex");
        }

        return View();
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Add(FormCollection form)
    {
        var member = Session[SessionStateKeys.Member] as Member;
        var meeting = TempData[TempDataKeys.CurrentMeeting] as Meeting; /* meeting ends up null here */

        if (member == null)
        {
            TempData[TempDataKeys.ErrorMessage] = "You must be logged in to add files to an meeting.";
            return RedirectToRoute("LoginPage");
        }

        if (meeting == null) 
        {
            TempData[TempDataKeys.ErrorMessage] = "An error occurred. No meeting selected.";
            return RedirectToRoute("MeetingsIndex");
        }

            // add files to meeting

        TempData[TempDataKeys.Notification] = "Successfully added.";
        return RedirectToRoute("AddFiles", new {meetingId = meeting.MeetingId});
}

編集:

ほとんどの回答に基づいて、TempData vs Sessionに保存する必要のあるデータ(メッセージ以外)の例を紹介できますか?

60
scottm

TempDataはセッションであるため、まったく違いはありません。ただし、 TempDataはリダイレクト用であり、リダイレクトのみ であるため、区別は簡単です。したがって、TempDataにメッセージを設定してからリダイレクトすると、TempDataが正しく使用されます。

ただし、あらゆる種類のセキュリティにSessionを使用することは非常に危険です。セッションとメンバーシップは、ASP.NETでは完全に分離されています。 他のユーザーからセッションを「盗む」ことができます 、そして、はい、人々はこの方法でウェブサイトを攻撃します。したがって、ユーザーがログインしているかどうかに基づいて投稿情報を選択的に停止する場合は、 IsAuthenticated を参照し、ログインしているユーザーのタイプに基づいて情報を選択的に表示する場合は、 ロールプロバイダー 。 GETはキャッシュできるため、GETのアクションへのアクセスを選択的に許可するonlyの方法はAuthorizeAttributeを使用します。

Update編集した質問への応答:質問でTempDataを使用する良い例が既にあります。つまり、POSTの失敗後に簡単なエラーメッセージを返す。 shouldがSessionに格納される(「あまりない」以外)の観点から、私はSessionをユーザー固有のキャッシュと考えています。非ユーザー固有のキャッシュと同様に、セキュリティ上重要な情報をそこに置かないでください。しかし、検索するには比較的高価なものを貼り付けるのに適した場所です。たとえば、Site.Masterにはユーザーのフルネームが表示されます。これはデータベースに保存され、提供するすべてのページに対してデータベースクエリを実行したくありません。 (私たちのアプリケーションのインストールは単一の会社で使用されているため、ユーザーのフルネームは「セキュリティの影響を受けやすい」とはみなされません。)ユーザーのCookieによって変化するキャッシュとセッションを考える場合、間違っている。

89
Craig Stuntz

既定のTempDataプロバイダーはセッションを使用するため、TempDataが次の要求の終わりにクリアされることを除いて、実際にはそれほど違いはありません。データが2つのリクエスト間でのみ保持される必要がある場合、TempDataを使用する必要があります。2番目のリクエストは、ユーザーからの他のリクエスト(AJAXなど)の問題を回避するためのリダイレクトです。データをそれより長く保持する必要がある場合は、TempDataを再移植するか、セッションを直接使用する必要があります。

17
tvanfosson

「機能しません」はあまり説明的ではありませんが、いくつかの提案を提供させてください。

内部では、TempDataはSessionを使用して値を保存します。そのため、ストレージメカニズムなどの点で大きな違いはありません。ただし、TempDataは次の要求が受信されるまでしか続きません。

ユーザーがフォーム送信の間にajaxリクエストを行うと、TempDataはなくなります。どんな要求でもTempDataはクリアされます。したがって、手動リダイレクトを実行している場合にのみ信頼性が高くなります。

表示フォームの非表示フィールドに会議IDを単純にレンダリングできないのはなぜですか?すでにモデルに追加しています。または、パラメータとしてルートに追加します。

4
womp

必要に応じて使用できます。明確化には、

TempData Vs セッション

TempData

  1. TempDataを使用すると、後続の単一の要求の間、データを永続化できます。
  2. ASP.net MVCは、連続する要求が結果を返すと、tempdataの値を自動的に期限切れにします(つまり、ターゲットビューが完全にロードされるまで有効です)。
  3. 現在および後続のリクエストにのみ有効
  4. TempDataには、TempDataの値を保持するKeepメソッドがあります。

    例:

    TempData.Keep()、TempData.Keep(“ EmpName”)

  5. TempDataは、セッション変数に値を内部的に保存しました。

  6. 検証メッセージ、エラーメッセージなどのワンタイムメッセージのみを保存するために使用されます。

セッション:

  1. セッションは、ユーザーセッションの有効期限が切れるまで、はるかに長い時間データを保存できます。
  2. セッションは、セッションタイムアウトが発生した後に期限切れになります。
  3. すべてのリクエストに有効です。
  4. なし
  5. セッション変数はSessionStateItemCollectionオブジェクトに保存されます(ページのHttpContext.Sessionプロパティを通じて公開されます)。
  6. これは、ユーザーID、ロールIDなど、ユーザーセッション全体で必要な長寿命データの保存に使用されます。

TempDataとセッション、どちらもデータを取得するために型キャストを必要とし、ランタイム例外を回避するためにnull値をチェックします。

4
iamCR

私はページ自体にそのようなデータを保持することを好みます。 meetingIDを非表示の入力としてレンダリングし、コントローラーに送信されるようにします。投稿を処理するコントローラーは、その会議IDをレンダリングされるビューにフィードバックできるため、基本的にmeetingIDは必要な限り渡されます。

それは、値を操作するメソッドを呼び出す前にグローバル変数に値を保存することと、値を直接メソッドに渡すこととの違いに似ています。

0
RedFilter

TempDataプロパティ値はセッション状態に保存されます。 TempDataの値は、読み取られるか、セッションがタイムアウトするまで保持されます。あるコントローラービューから別のコントローラービューにデータを渡す場合は、TempDataを使用する必要があります。

データがアプリケーション全体に必要な場合にセッションを使用する

0
Mervin

MvcContribのソリューションをお勧めします: http://jonkruger.com/blog/2009/04/06/aspnet-mvc-pass-parameters-when-redirecting-from-one-action-to-another/ =

完全なMvcContribが必要ない場合、解決策はMvcContribソースから簡単に取得できる1つのメソッド+ 1つのクラスのみです。

0
queen3