@Html.EditForとTextForの違いと使い方

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

ASP.NET MVCのRazorビューでフォームを扱う際に頻出する@Html.EditForTextFor。似たような名前ですが、それぞれの役割や使い分けを正しく理解しているでしょうか?この記事では、それぞれのメソッドの違い、使いどころ、サンプルコードを交えて実践的に解説します。初心者から中級者まで、フォーム開発の理解を一段深めたい方におすすめの内容です。

EditForとTextForの基本的な違い

EditorForTextBoxForは、いずれもASP.NET MVCのRazorビューでモデルのプロパティをバインドするためのHTMLヘルパーですが、その性質は大きく異なります。ここでは、それぞれの基本的な違いとその設計思想を紹介します。

自動テンプレート生成 vs 明示的な制御

@Html.EditorFor はモデルに基づく入力フィールドを自動生成します。プロパティの型(string, int, DateTimeなど)に応じて適切な入力フィールド(<input>, <textarea>, <select> など)を自動的に選んで生成してくれます。これは、「テンプレートヘルパー」としての役割を持ち、迅速な開発に向いています。

一方で @Html.TextBoxFor は常にテキストボックス(<input type="text">)を生成します。つまり、型にかかわらずテキスト入力欄として固定的にレンダリングされ、開発者が明示的にHTML属性やクラスを指定して制御するスタイルです。

ASP.NET MVCの例

<!-- string型でも、EditorForはtextareaになる場合がある -->
@Html.EditorFor(model => model.Description)

<!-- 明示的にテキストボックスを出力 -->
@Html.TextBoxFor(model => model.Description)

このように、テンプレートベースか明示的なHTML制御かという観点で両者を使い分けることがポイントです。

EditorForの特徴と活用ポイント

EditorForは、ASP.NET MVCの強力なテンプレート機能を活用できる便利なヘルパーです。特に大規模なアプリケーションで再利用性を高めるのに役立ちます。

モデルに基づくテンプレートによる自動生成

✅ 型情報をもとに、ASP.NET MVCが自動的に適切な入力コントロールを選びます。例えば、DateTime型であれば、日付用の入力フィールドが生成されます。これにより、個別にコントロールを指定する手間を省くことができます。

バリデーションとの親和性

DataAnnotations属性(例:[Required], [StringLength], [Display]など)と連携し、クライアント側バリデーションとサーバー側バリデーションの両方に対応できます。表示名も自動的に[Display(Name="xxx")]属性に従ってレンダリングされます。

カスタムエディターの作成手順(コピペで使えるサンプル)

ここでは、DateTime型のプロパティに対して、カスタム日付入力を提供する方法を具体的なサンプルコードとともに紹介します。

✅ 前提

以下の3ファイルをプロジェクトに追加してください:

  1. モデルファイル(UserModel.cs
  2. ビューファイル(Edit.cshtmlなど)
  3. カスタムテンプレートファイル(Views/Shared/EditorTemplates/DateTime.cshtml

1. モデルファイルの作成

ファイル名:Models/UserModel.cs

using System;
using System.ComponentModel.DataAnnotations;

namespace YourNamespace.Models
{
    public class UserModel
    {
        [Display(Name = "誕生日")]
        public DateTime? BirthDate { get; set; }

        [Display(Name = "氏名")]
        public string Name { get; set; }
    }
}

2. ビューファイルの作成(EditorFor使用)

ファイル名:Views/User/Edit.cshtml

@model YourNamespace.Models.UserModel

@{
    ViewBag.Title = "ユーザー編集";
}

<h2>ユーザー編集</h2>

@using (Html.BeginForm()) {
    <div class="form-group">
        @Html.LabelFor(model => model.Name)
        @Html.TextBoxFor(model => model.Name, new { @class = "form-control" })
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.BirthDate)
        @Html.EditorFor(model => model.BirthDate)
    </div>

    <button type="submit" class="btn btn-primary">送信</button>
}

3. カスタムテンプレートの作成

ファイル名:Views/Shared/EditorTemplates/DateTime.cshtml

※フォルダ構成が重要です!必ずこのパスで保存してください。

@model DateTime?

@{
    var fullName = ViewData.TemplateInfo.GetFullHtmlFieldName("");
    var fullId = ViewData.TemplateInfo.GetFullHtmlFieldId("");
    var value = Model.HasValue ? Model.Value.ToString("yyyy-MM-dd") : "";
}

<input type="date"
       name="@fullName"
       id="@fullId"
       value="@value"
       class="form-control" />

動作確認方法

  1. コントローラーからUserModelを渡してEditビューを表示。
  2. BirthDateにカレンダー付きの<input type="date">が表示されれば成功です。
  3. 同じDateTime型のプロパティが他のビューにあっても、同じテンプレートが自動で適用されます。

このコードをそのままプロジェクトに組み込むことで、再利用可能なカスタムエディターを簡単に導入できます。テンプレートを拡張することで、さらに複雑なUIも柔軟に対応できます。

✅ readonlyや任意の属性を扱えるEditorTemplatesのサンプル

以下は、readonlyplaceholderclass などの任意属性をテンプレート側で扱えるように改良したテンプレートです。

ファイル:Views/Shared/EditorTemplates/DateTime.cshtml

@model DateTime?

@using System.Web.Mvc
@{
    var fullName = ViewData.TemplateInfo.GetFullHtmlFieldName("");
    var fullId = ViewData.TemplateInfo.GetFullHtmlFieldId("");
    var value = Model.HasValue ? Model.Value.ToString("yyyy-MM-dd") : "";

    var htmlAttributes = new Dictionary<string, object>(ViewData["htmlAttributes"] as IDictionary<string, object> ?? new Dictionary<string, object>());

    htmlAttributes["type"] = "date";
    htmlAttributes["name"] = fullName;
    htmlAttributes["id"] = fullId;
    htmlAttributes["value"] = value;

    var tagBuilder = new TagBuilder("input");
    tagBuilder.MergeAttributes(htmlAttributes);
}

@Html.Raw(tagBuilder.ToString(TagRenderMode.SelfClosing))

使い方(ビュー側)

@Html.EditorFor(model => model.BirthDate, new { htmlAttributes = new { @class = "form-control", @readonly = "readonly", placeholder = "生年月日" } })

✅ 上記の書き方で、以下のHTMLが出力されます:

<input type="date" name="BirthDate" id="BirthDate" value="2024-12-31" class="form-control" readonly="readonly" placeholder="生年月日" />

🔧 補足ポイント

  • EditorForは引数に ViewDataDictionary を渡せないため、特殊キーとして htmlAttributes を使うのがASP.NET MVCでの定石です。
  • カスタムテンプレート内で ViewData["htmlAttributes"] を受け取り、TagBuilder で動的にマージすることで、任意属性が反映されます。

TextBoxForの特徴と活用ポイント

TextBoxForは、より細かく出力をコントロールしたい場面で活躍します。特に、BootstrapなどのCSSフレームワークとの連携を考慮したUIカスタマイズに向いています。

HTML属性の細かな制御が可能

new { @class = "form-control", placeholder = "名前を入力" }のように、HTML属性を直接指定できます。デザイン制約が厳しい場合や、JavaScriptとの連携を意識した場合に便利です。

単純なテキスト入力に向いている

✅ 型に関係なく常に<input type="text">を生成するため、フォームの仕様が固定されている場面では意図通りの出力を得やすくなります。

モデルに依存しすぎない柔軟さ

✅ 型に依存しないため、動的にプロパティを処理したいケースや、同じUIで複数の型を使い回すような場面でも適応しやすい設計です。

ASP.NET MVCの例

@Html.TextBoxFor(model => model.Name, new {
    @class = "form-control",
    placeholder = "フルネームを入力してください"
})

使用シーンに応じた使い分け例

どちらのヘルパーを使うかは、画面の用途や要件によって適切に選ぶことが重要です。ここでは典型的なシーンごとに使い分けの考え方を紹介します。

ユーザー情報の編集フォーム

高速開発や再利用性を重視する場合は、EditorForを使って必要な入力フィールドを一括で自動生成。共通テンプレートを用意すれば、保守も効率的です。

日付・数値など特殊フォーマットの入力

✅ 日付専用のカレンダー入力や数値のみの入力など、フォーマット指定が重要な場合はTextBoxForとHTML5属性を組み合わせると便利です。

@Html.TextBoxFor(model => model.BirthDate, new {
    @type = "date",
    @class = "form-control"
})

部分ビューでの再利用設計

部分ビューで共通フォーム部品を使い回す場合は、EditorTemplatesEditorForの組み合わせが適しています。テンプレートさえ整備すれば、多様なモデルにも適応可能です。

サンプルコードで学ぶ実装例

以下は、UserModelを例に、EditorForTextBoxForの具体的な使い分けを示したサンプルです。

@model UserModel

<!-- EditorForの例:テンプレートに基づいた自動生成 -->
@Html.EditorFor(model => model.Name)

<!-- TextBoxForの例:クラスや属性を明示的に指定 -->
@Html.TextBoxFor(model => model.Name, new { @class = "form-control", placeholder = "氏名を入力" })

どちらもmodel.Nameにバインドしていますが、出力されるHTMLやスタイリングの自由度に違いがある点に注目してください。

まとめ

RazorビューにおけるEditorForTextBoxForの違いを理解して使い分けることで、保守性の高いフォームを設計できます。テンプレートベースで自動生成されるEditorForは素早い開発に向いています。一方、デザインや動作を細かく調整したい場面では、TextBoxForが有効です。

プロジェクトの要件や再利用性を意識して、適切なHTMLヘルパーを選択することで、より効率的で拡張性の高いWebアプリケーション開発が実現できるでしょう。

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

コメント

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