33

ViewBag については、使用禁止と聞いていました。ViewBag のコンテンツをビュー モデルに組み込む必要があると思いますか?

質問:

  1. ベストプラクティスを超える私の仮定です。(ViewBag を使用せず、2 番目にビュー モデルに含める)

  2. ViewBag が絶対に必要な状況はありますか?

4

11 に答える 11

32

1)ベストプラクティスを超える私の仮定です。(ViewBag を使用せず、2 番目にビュー モデルに含める)

可能な限り、ViewBag を介してデータを渡す代わりに、ビューモデルを使用する必要があります。

2) ViewBag が絶対に必要な状況はありますか?

ViewBag が絶対に必要な状況はありません。ただし、View Model の代わりに ViewBag を使用することを個人的に好むデータがいくつかあります。たとえば、定義済みの値 (都市など) のドロップダウン ボックスにデータを入力する必要がある場合、ViewBag を使用して SelectListItem 配列を表示します。ViewModel をこのデータで汚染したくないのです。

于 2012-06-29T13:31:37.060 に答える
32

ViewBag は動的辞書です。そのため、ViewBag を使用してアクション メソッドとビューの間でデータを転送する場合、ビュー内の ViewBag 項目にアクセスしようとしたときにコードに入力ミスがあると、コンパイラはそれを検出できません。ビューは実行時にクラッシュします:(

一般に、ビュー モデルを使用してアクション メソッドとビューの間でデータを転送することをお勧めします。ビュー モデルは、ビューに固有のプロパティを持つ単純な POCO クラスです。したがって、ビューに追加のデータを渡したい場合は、ビュー モデルに新しいプロパティを追加し、それを使用します。厳密に型指定されたビューにより、コードがよりクリーンになり、保守がより簡単になります。このアプローチでは、ビューバッグで行う必要があるいくつかのタイプへのビューバッグ辞書アイテムの明示的なキャストを行う必要はありません。

public class ProductsForCategoryVm
{
  public string CategoryName { set;get; }
  public List<ProductVm> Products { set;get;}    
}
public class ProductVm
{
  public int Id {set;get;} 
  public string Name { set;get;}
}

アクション メソッドで、このビュー モデルのオブジェクトを作成し、プロパティを読み込んでビューに送信します。

public ActionResult Category(int id)
{
  var vm= new ProductsForCategoryVm();
  vm.CategoryName = "Books";
  vm.Products= new List<ProductVm> {
     new ProductVm { Id=1, Name="The Pragmatic Programmer" },
     new ProductVm { Id=2, Name="Clean Code" }
  }
  return View(vm);
}

そして、ビューモデルに強く型付けされたビューは、

@model ProductsForCategoryVm
<h2>@Model.CategoryName</h2>
@foreach(var item in Model.Products)
{
    <p>@item.Name</p>
}

ドロップダウン データ ?

多くのチュートリアル/書籍には、ドロップダウン データに ViewBag を使用するコード サンプルがあります。個人的には、これには ViewBag を使用すべきではないと今でも感じています。List<SelectListItemドロップダウン データを渡すには、ビュー モデルで >タイプのプロパティである必要があります。これを行う方法に関するサンプルコードを含む投稿があります。

ViewBag が絶対に必要な状況はありますか?

ViewBag を使用してデータを送信できる (必須ではありません)有効な使用例がいくつかあります。たとえば、レイアウト ページに何かを表示したい場合、そのために ViewBag を使用できます。もう 1 つの例ViewBag.Title (ページ タイトル) は、既定の MVC テンプレートにあります。

public ActionResult Create()
{
   ViewBag.AnnouncementForEditors="Be careful";
   return View();
}

レイアウトでは、ViewBag.AnnouncementForEditors

<body>
<h1>@ViewBag.AnnouncementForEditors</h1>
<div class="container body-content">
    @RenderBody()
</div>
</body>
于 2012-06-29T12:50:40.243 に答える
5

1)ベストプラクティスを超える私の仮定です。(ViewBag を使用せず、2 番目にビュー モデルに含める)

はい。

2) ViewBag が絶対に必要な状況はありますか?

いいえ。ViewBag に保存したものはすべて、ビューに渡されたビュー モデルに入る可能性があります。

于 2012-06-29T12:49:46.650 に答える
4

ViewBags と推奨されるベスト プラクティスの問題は、コンパイル時間のチェックに要約されます。ViewBags は単なる辞書であり、それを使用して「魔法の」文字列を取得するため、viewbag 項目のいずれかのオブジェクト タイプまたはキー名を変更することになった場合、<MvcBuildViews>true</MvcBuildViews>.

特定のビューに合わせてモデルを変更する必要がある場合でも、ビュー モデルに固執するのが最善です。

于 2012-06-29T12:54:37.813 に答える
2

すべてのページに共通の機能があり、その機能が表示されているページに依存しない ViewBag の用途をいくつか見つけました。たとえば、StackOverflow を構築しているとします。求人掲示板は各ページに表示されますが、表示される求人はそのページとは関係ありません (私の使い方はコンセプトが似ていました)。各 ViewModel にプロパティを追加するのは難しく、時間がかかり、テストに多くの手間がかかります。この状況下では割に合わないと思います。

私はクロスカッティングデータで基本ViewModelクラスを使用しましたが、複数の場合(ジョブとスタック交換サイトのリストなど)、余分なデータを詰め込むか、ViewModelの他の悪用を開始する必要があります。基本データを設定するには、ViewModel ビルダーが必要です。

魔法の糸の問題に関しては、多くの解決策があります。定数、拡張メソッドなど

とはいえ、ページのコンテキストに応じてページに表示されるものがある場合は、ViewModel が役に立ちます。

エリック

于 2012-06-29T18:44:59.080 に答える
1

既存の ViewModel を再設計できない場合は、ViewBag を使用してください。

于 2013-10-17T16:25:28.263 に答える
1
  1. いいえ。 ViewModelsを使用してください。
  2. いいえ。完璧な ViewModel を設計する場合、ViewBag は必要ありません。
于 2012-06-29T12:48:49.870 に答える