ViewBagとViewDataをスマートに使い分ける

システム開発
スポンサーリンク
スポンサーリンク

ASP.NET MVC/Coreで、「ページタイトルをLayoutに渡したい」「一時的にメッセージを表示したい」などの場面で、ViewBagViewDataを使ったことはありませんか?これらはどちらも「軽量なデータ渡し手段」として便利ですが、仕組みや用途を正しく理解していないと、保守性の低下やバグの原因になってしまうことも。

本記事では、両者の基本構造から違い、典型的な使い分け例、現場でありがちな落とし穴までを整理します。「型安全なViewModelが第一、補助的にViewBag/ViewData」という原則をベースに、適材適所の判断ができるようになりましょう。

ViewBagとViewDataの基本的な違い

ここでは、ViewBagとViewDataがどのような性質を持っていて、何が異なるのかを比較形式で整理します。

ViewBagは dynamic、ViewDataは 辞書型

特性 ViewBag ViewData
dynamic IDictionary<string, object>
補完 一部効く 効かない
型チェック 実行時 実行時(キャスト要)

ViewBag の特徴

  • dynamic を使った糖衣構文(ViewBag.Message = "Hello"
  • 内部的には ViewData["Message"] をラップしている
  • 型安全性がないため、タイポによる実行時エラーのリスクがある

⚠️ 失敗例(タイポ)

ViewBag.Mesage = "こんにちは"; // Message のつもりが誤字

<h2>@ViewBag.Message</h2> // nullが表示されるがエラーにならない

ViewData の特徴

  • object 型の辞書構造(キャストが必要)
  • 動的なキー操作が得意(ループ処理など)
  • 補完が効かず、ミスを防ぐ仕組みが弱い

⚠️ 冗長な記述

<p>年齢: @(int)ViewData["Age"]</p>

仕組みの違いと技術的背景

このセクションでは、内部的にどう動作しているか、ライフサイクルやパフォーマンスなどの観点から違いを見ていきます。

共通点:同じライフサイクル

  • 両者とも HTTPリクエスト単位で生成される
  • セッションのようにリクエスト間で値を持ち越すことはできない

👉 どのくらい値が保持されるのか?

  • ViewBag / ViewData の値は、1回のHTTPリクエスト内のみ有効です。
  • return View() のときはビューで使用可能ですが、RedirectToAction() などのリダイレクトでは失われます。
  • リクエストをまたいで値を保持したい場合は TempDataSession などを使いましょう。

ViewBagの dynamic 利便性と落とし穴

  • 補完機能のあるエディタ(Visual Studioなど)では使いやすい
  • ただし、存在しないプロパティを指定しても気づけない

ViewDataの柔軟性

  • 辞書ベースのため、繰り返し処理や動的キー構成が可能
  • ViewData["Error_1"], ViewData["Error_2"] などのパターン処理に強い

パフォーマンス面の違い

  • ViewBagdynamicによるリフレクションが介在し、わずかなオーバーヘッドあり
  • 一方で、数件程度のデータであれば体感差はほとんどない

使い分けのベストプラクティス

「ViewBagとViewData、どちらを使うべきか」に迷う場面は多いものです。ここでは判断の目安となる方針と、用途ごとの具体例を示します。

✅ 原則:まずViewModel、それ以外は例外的用途

ViewModelを使うべきケース:

  • 明示的にビューへ複数の値を渡す
  • 型安全や補完機能が重要
  • 中規模以上のビュー

ViewBag/ViewDataを使ってよいケース:

  • 一時的な通知、メッセージ表示
  • Layoutや部分ビューに軽量な情報を渡す
  • 仮実装やプロトタイプ段階での簡易表示

✅ ViewBag の適用例

// Controller
ViewBag.PageTitle = "ダッシュボード";

<!-- Layout.cshtml -->
<title>@ViewBag.PageTitle - MyApp</title>

こんなときに便利:

  • Layoutに共通タイトルを渡したい
  • ViewModelを拡張せずに暫定で画面表示をしたい

✅ ViewData の適用例(繰り返しや連番キー)

// Controller
ViewData["Error1"] = "名前が未入力です";
ViewData["Error2"] = "パスワードが短すぎます";

@for (int i = 1; i <= 2; i++)
{
  <p class="text-danger">@ViewData[$"Error{i}"]</p>
}

こんなときに便利:

  • 同じ構造の複数データを処理したい
  • ループや条件分岐が必要な場面

ViewModelとの比較

ここでは、型安全性が確保されるViewModelを使った記述との違いを示し、ViewBag/ViewDataとの対比を行います。

// モデルクラス
public class InfoViewModel
{
    public string Message { get; set; }
    public int Count { get; set; }
}

// Controller
public IActionResult Info()
{
    var model = new InfoViewModel
    {
        Message = "ようこそ!",
        Count = 5
    };
    return View(model);
}

@model InfoViewModel

<h2>@Model.Message</h2>
@for (int i = 0; i < Model.Count; i++)
{
    <p>@i 番目</p>
}

ViewModelの強み:

  • 静的型付けで安全
  • プロパティの誤りをコンパイル時に検出
  • チーム開発やリファクタリングに強い

早見表:ViewBag/ViewDataの比較

どちらを使えばよいか迷ったときのために、判断材料となる比較表を用意しました。

比較項目 ViewBag ViewData
型安全性
補完機能 ✅(一部)
型キャスト必要
動的キー処理
使用シーン 軽量な表示、Layout用 ループ、連番キー
NG例 タイポでnullになる キーの競合で上書きミス

まとめ:正しく使えば強力なツール

最後に、これまでのポイントを振り返り、実務での選択判断に役立つ指針を整理します。

  • ViewBagViewDataは便利だが、「仮の用途」や「軽量用途」に限定すべき
  • 複数値や構造的なデータは必ず ViewModel を活用
  • 設計判断に迷ったら「型安全性と保守性」を最優先に考える

最終的に目指すべきは、“混在しない、意図の明確なコード”です。 ViewBagViewDataも、適切に使えば実務で大いに役立つツールです。選択の軸を明確にし、チーム内で統一された運用ルールを持つことが、バグのない生産的な開発につながります。

システム開発
スポンサーリンク
tobotoboをフォローする

コメント

タイトルとURLをコピーしました