ViewBag、ViewData、およびTempData


209

どんな体がいつ使うべきか説明できますか

  1. TempData
  2. ViewBag
  3. ViewData

コントローラー1に値を設定する必要があるという要件があります。そのコントローラーはコントローラー2にリダイレクトし、コントローラー2はビューをレンダリングします。

私はViewBagを使用しようとしましたが、コントローラ2に到達するまでに値が失われます。

いつ使用するか、利点または欠点を知ることができますか?

ありがとう


5
これは違いを説明する素晴らしい記事です。
Beku

1
stackoverflow.com/a/17199709/2015869
Imad Alazani 2013年

回答:


293

1)TempData

リダイレクト後も存続するデータを保存できます。内部的にはセッションをバッキングストアとして使用し、リダイレクトが行われた後、データは自動的に削除されます。パターンは次のとおりです。

public ActionResult Foo()
{
    // store something into the tempdata that will be available during a single redirect
    TempData["foo"] = "bar";

    // you should always redirect if you store something into TempData to
    // a controller action that will consume this data
    return RedirectToAction("bar");
}

public ActionResult Bar()
{
    var foo = TempData["foo"];
    ...
}

2)ViewBag、ViewData

対応するビューで使用されるコントローラーアクションにデータを保存できます。これは、アクションがビューを返し、リダイレクトしないことを前提としています。現在のリクエストの間のみ有効です。

パターンは次のとおりです。

public ActionResult Foo()
{
    ViewBag.Foo = "bar";
    return View();
}

そしてビューで:

@ViewBag.Foo

またはViewDataを使用:

public ActionResult Foo()
{
    ViewData["Foo"] = "bar";
    return View();
}

そしてビューで:

@ViewData["Foo"]

ViewBag 周りの動的なラッパーです ViewDataあり、ASP.NET MVC 3にのみ存在します。

これは言われているが、これらの2つの構成のいずれも決して使用すべきではない。ビューモデルと厳密に型指定されたビューを使用する必要があります。したがって、正しいパターンは次のとおりです。

モデルを見る:

public class MyViewModel
{
    public string Foo { get; set; }
}

アクション:

public Action Foo()
{
    var model = new MyViewModel { Foo = "bar" };
    return View(model);
}

強く型付けされたビュー:

@model MyViewModel
@Model.Foo

この簡単な紹介の後、あなたの質問に答えましょう:

私の要件は、コントローラー1に値を設定することです。そのコントローラーはControllerTwoにリダイレクトし、Controller2はビューをレンダリングします。

public class OneController: Controller
{
    public ActionResult Index()
    {
        TempData["foo"] = "bar";
        return RedirectToAction("index", "two");
    }
}

public class TwoController: Controller
{
    public ActionResult Index()
    {
        var model = new MyViewModel
        {
            Foo = TempData["foo"] as string
        };
        return View(model);
    }
}

および対応するビュー(~/Views/Two/Index.cshtml):

@model MyViewModel
@Html.DisplayFor(x => x.Foo)

TempDataの使用には欠点もあります。ユーザーがターゲットページでF5キーを押すと、データが失われます。

個人的にはTempDataも使用していません。内部でSessionを使用しており、アプリケーションでセッションを無効にしているためです。これを実現するには、よりRESTfulな方法を好みます。つまり、リダイレクトを実行する最初のコントローラーアクションでは、オブジェクトをデータストアに保存し、リダイレクト時に生成された一意のIDを使用します。次に、ターゲットアクションでこのIDを使用して、最初に保存されたオブジェクトをフェッチします。

public class OneController: Controller
{
    public ActionResult Index()
    {
        var id = Repository.SaveData("foo");
        return RedirectToAction("index", "two", new { id = id });
    }
}

public class TwoController: Controller
{
    public ActionResult Index(string id)
    {
        var model = new MyViewModel
        {
            Foo = Repository.GetData(id)
        };
        return View(model);
    }
}

ビューは同じままです。


57
すばらしい答えですが、「これら2つの構成体のいずれも使用してはならない」という独断的な声明には同意しません。ViewBagの正当な使用法をいくつか見つけました。たとえばViewBag.Title_Layout.cshtmlベースビューファイルで使用されるすべてのビューにプロパティを設定します。私がそれを使用するもう1つのケースは、ユーザーに情報メッセージ(たとえば、「製品は正常に保存されました!」)を与えることです。Layout.cshtml提供されている場合はメッセージをレンダリングするためにいくつかの汎用マークアップを配置しましたViewBag.Message。これにより、任意のアクションで設定できます。どちらの場合にもViewModelプロパティを使用すると、デメリットが多すぎます。
Jesse Webb

22
私はJesseに同意する必要がありますが、これは優れた説明ですが、ViewBagを使用する正当な理由がないことを露骨に述べているのは、意見の問題であり、事実の問題ではありません。ViewBagを使いすぎるのは確かに悪い習慣であり、一部の開発者はこの罠に陥りますが、上品に使用することは強力なリソースです。
Ron DeFreitas

1
@ ron.defreitasは、大丈夫、あなたが使用する理由一つの良い理由を教えてくださいViewBag。ViewBagに用途がある場合の具体的な現実のシナリオを説明してください。あなたがそうだと言っているので、私は強力なリソースを引用ますが、この強力なリソース強力である特定のケースがあると思います。私はこれをキャリアで使用したことがないので、人々がこの強力な武器をどのように使用しているかを学ぶことができてとても幸せです。
Darin Dimitrov

27
ここにはエリート主義者がいます。Darin、Jesseはそのような例の1つを具体的に述べました。物事を行う他の方法が常にあるからといって、それらの有用性が自動的に無効になるわけではありません。
ジェントルマン

2
@DarinDimitrov:現在、属性メソッド内からビューに情報を渡す必要があるシナリオがあります。filterContext.Controller.ViewDataを使用すると、厳密に型指定されたビューに渡そうとするよりもはるかに簡単です。とはいえ、説明ありがとうございます、とても役に立ちました。
アンディ

15

ASP.NET MVCには、コントローラーからビューにデータを渡し、次のリクエストでデータを渡すためのViewData、ViewBag、TempDataの3つのオプションがあります。ViewDataとViewBagはほぼ同じで、TempDataが追加の責任を果たします。これら3つのオブジェクトの重要なポイントについて説明または取得します。

ViewBagとViewDataの類似点:

  • コントローラからビューに移動するときにデータを維持するのに役立ちます。
  • コントローラから対応するビューにデータを渡すために使用されます。
  • 短い寿命とは、リダイレクトが発生したときに値がnullになることを意味します。これは、コントローラーとビューの間で通信する方法を提供することを目的としているためです。これは、サーバー呼び出し内の通信メカニズムです。

ViewBagとViewDataの違い:

  • ViewDataは、ViewDataDictionaryクラスから派生したオブジェクトのディクショナリであり、キーとして文字列を使用してアクセスできます。
  • ViewBagは、C#4.0の新しい動的機能を利用する動的プロパティです。
  • ViewDataは、複雑なデータ型の型キャストを必要とし、エラーを回避するためにnull値をチェックします。
  • ViewBagは、複雑なデータ型の型キャストを必要としません。

ViewBagとViewDataの例:

public ActionResult Index()
{
    ViewBag.Name = "Monjurul Habib";
    return View();
}


public ActionResult Index()
{
    ViewData["Name"] = "Monjurul Habib";
    return View();
} 

ビューで:

@ViewBag.Name 
@ViewData["Name"] 

TempData:

TempDataもTempDataDictionaryクラスから派生したディクショナリであり、短期間のセッションに格納され、文字列キーとオブジェクト値です。違いは、オブジェクトのライフサイクルです。TempDataは、HTTPリクエスト時の情報を保持します。これは、あるページから別のページへの移動のみを意味します。同じHTTPリクエスト内にあるため、これは302/303リダイレクションでも機能します。1つのコントローラーから別のコントローラーに、または1つのアクションから別のアクションに移動するときにデータを維持するのに役立ちます。つまり、リダイレクトする場合、「TempData」はそれらのリダイレクト間でデータを維持するのに役立ちます。内部的にセッション変数を使用します。現在および後続のリクエスト中の一時データの使用は、次のリクエストが次のビューにリダイレクトされることが確実な場合にのみ使用されることを意味します。エラーを回避するには、複雑なデータ型の型キャストとnull値のチェックが必要です。

public ActionResult Index()
{
  var model = new Review()
            {
                Body = "Start",
                Rating=5
            };
    TempData["ModelName"] = model;
    return RedirectToAction("About");
}

public ActionResult About()
{
    var model= TempData["ModelName"];
    return View(model);
}

最後のメカニズムは、キーとして文字列を受け取り、値としてオブジェクトを受け取るディクショナリのように、ViewDataのように機能するセッションです。これはクライアントのCookieに保存され、はるかに長い間使用できます。機密情報を決して持たないようにするには、さらに検証が必要です。ViewDataまたはViewBagについては、アプリケーションのパフォーマンスのためにインテリジェントに使用する必要があります。各アクションは通常のasp.net mvcリクエストのライフサイクル全体を通過するためです。子アクションでViewData / ViewBagを使用できますが、コントローラーを汚染する可能性のある無関係なデータを入力するためにそれを使用していないことに注意してください。


11

TempData

基本的にはDataReaderのようなもので、一度読み取るとデータは失われます。

このビデオをチェック

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Message = "Welcome to ASP.NET MVC!";
        TempData["T"] = "T";
        return RedirectToAction("About");
    }

    public ActionResult About()
    {
        return RedirectToAction("Test1");
    }

    public ActionResult Test1()
    {
        String str = TempData["T"]; //Output - T
        return View();
    }
}

上記のコードに注意を払うと、RedirectToActionはTempDataが読み取られるまでTempDataに影響を与えません。したがって、TempDataが読み取られると、値は失われます。

読み取り後にTempDataを保持するにはどうすればよいですか?

アクションメソッドテスト1とテスト2の出力を確認します。

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Message = "Welcome to ASP.NET MVC!";
        TempData["T"] = "T";
        return RedirectToAction("About");
    }

    public ActionResult About()
    {
        return RedirectToAction("Test1");
    }

    public ActionResult Test1()
    {
        string Str = Convert.ToString(TempData["T"]);
        TempData.Keep(); // Keep TempData
        return RedirectToAction("Test2");
    }

    public ActionResult Test2()
    {
        string Str = Convert.ToString(TempData["T"]); //OutPut - T
        return View();
    }
}

上記のコードに注意を払えば、RedirectToActionの後、およびデータの読み取り後にデータが失われることはありませんTempData.Keep()。その理由は、を使用しているためです。それは

このようにして、他のコントローラーでも必要なだけ持続させることができます。

ViewBag / ViewData

データは対応するビューに保持されます


4

Asp.Net MVCのTempDataは非常に便利な機能の1つです。現在のリクエストから後続のリクエストにデータを渡すために使用されます。つまり、リダイレクトが発生している間にあるページから別のページにデータを送信したい場合は、TempDataを使用できますが、MVCでこの機能を実現するためにコードでいくつかの検討を行う必要があります。TempDataの寿命は非常に短く、ターゲットビューが完全にロードされるまでしか存在しないためです。ただし、Keep()メソッドを使用してデータをTempDataに永続化できます。

続きを読む


3

MVCでのViewBag、ViewData、TempData、およびView State

http://royalarun.blogspot.in/2013/08/viewbag-viewdata-tempdata-and-view.html

ASP.NET MVCには、コントローラーからビューにデータを渡し、次のリクエストでデータを渡すためのViewData、VieBag、TempDataの3つのオプションがあります。ViewDataとViewBagはほぼ同じで、TempDataが追加の責任を果たします。

ViewBagとViewDataの類似点:

コントローラからビューに移動するときにデータを維持するのに役立ちます。コントローラから対応するビューにデータを渡すために使用されます。短い寿命とは、リダイレクトが発生したときに値がnullになることを意味します。これは、コントローラーとビューの間で通信する方法を提供することを目的としているためです。これは、サーバー呼び出し内の通信メカニズムです。

ViewBagとViewDataの違い:

ViewDataは、ViewDataDictionaryクラスから派生したオブジェクトのディクショナリであり、キーとして文字列を使用してアクセスできます。ViewBagは、C#4.0の新しい動的機能を利用する動的プロパティです。ViewDataは、複雑なデータ型の型キャストを必要とし、エラーを回避するためにnull値をチェックします。ViewBagは、複雑なデータ型の型キャストを必要としません。

ViewBagとViewDataの例:

public ActionResult Index()

{  
    ViewBag.Name = "Arun Prakash";
    return View();    
}

public ActionResult Index()  
{
    ViewData["Name"] = "Arun Prakash";
    return View(); 
}

Viewでは、次のように呼び出します。

@ViewBag.Name   
@ViewData["Name"]

TempData:

1つのコントローラーから別のコントローラーに、または1つのアクションから別のアクションに移動するときにデータを維持するのに役立ちます。つまり、リダイレクトするとき、「Tempdata」はそれらのリダイレクト間でデータを維持するのに役立ちます。内部的にセッション変数を使用します。TempDataは非常に短期間のインスタンスであることを意図しており、現在のリクエストと後続のリクエストのみで使用する必要があります

TempDataの使用が確実に機能する唯一のシナリオは、リダイレクトする場合です。これは、リダイレクトによって現在の要求が強制終了され(クライアントにHTTPステータスコード302 Object Movedが送信され)、リダイレクトされたビューを提供するためにサーバー上に新しい要求が作成されるためです。

エラーを回避するには、複雑なデータ型の型キャストとnull値のチェックが必要です。

public ActionResult Index()
{   
   var model = new Review()  
   {  
      Body = "Start",  
      Rating=5  
   };  

    TempData["ModelName"] = model;    
    return RedirectToAction("About");   
} 

public ActionResult About()       
{  
    var model= TempData["ModelName"];  
    return View(model);   
}  

1
void Keep()

Calling this method with in the current action ensures that all the items in TempData are not removed at the end of the current request.

    @model MyProject.Models.EmpModel;
    @{
    Layout = "~/Views/Shared/_Layout.cshtml";
    ViewBag.Title = "About";
    var tempDataEmployeet = TempData["emp"] as Employee; //need typcasting
    TempData.Keep(); // retains all strings values
    } 

void Keep(string key)

Calling this method with in the current action ensures that specific item in TempData is not removed at the end of the current request.

    @model MyProject.Models.EmpModel;
    @{
    Layout = "~/Views/Shared/_Layout.cshtml";
    ViewBag.Title = "About";
    var tempDataEmployeet = TempData["emp"] as Employee; //need typcasting
    TempData.Keep("emp"); // retains only "emp" string values
    } 

1

TempDataは最初の読み取りまで常に利用可能です。一度読み取ると、もう利用できなくなり、最初の読み取り後に消えてしまうビューにクイックメッセージを渡すのに役立ちます。ViewBagは、データの一部をすばやくビューに渡す場合に便利です。通常、すべてのデータをmodelを介してビューに渡す必要がありますが、エンティティフレームワークのようにデータベースにマップされているクラスから直接モデルを作成する場合があります。新しいデータを渡すためにモデルを変更する必要はありません。それをビューバッグに貼り付けることができます。ViewDataは、インデックス付きバージョンのViewBagであり、MVC3の前に使用されていました。


0

また、viewbagとtemptdataではスコープが異なります。viewbagは最初のビュー(アクションメソッド間で共有されない)に基づいていますが、temptdataはアクションメソッドとお互いの間で共有できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.