しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

DisplayFor/EditorFor と DataType の不文律

ASP.NET MVC 3 のスキャフォールディングを使うと、DisplayFor と EditorFor を使ったビューを生成してくれますよね。

ネットの海を彷徨ってみると、DisplayTemplates と EditorTemplates というディレクトリを用意すると、自由に出力を変えることが出来るよ!と書いてることが多いですが、実はデフォルトのテンプレートが優秀だったりしますよ。

とりあえず実際に紹介しつつ見ていきましょうか。まずは表示の方から。

DisplayFor

以下の型に対してデフォルトのテンプレートを持っています。

  • メールアドレス
  • 隠しフィールド (input type=hidden)
  • HTML
  • テキスト
  • URL
  • コレクション
  • bool
  • decimal
  • string
  • object

string や object は特に変わり映えのない、そのまま出力するだけのテンプレートです。コレクションは正直使い道が浮かびません・・・。なのでそれ以外のテンプレートを試してみます。

用意したモデルクラスはこんな感じ。単純ですね、ええ。

public class DisplayModel
{
    public int Id { get; set; }

    [DataType(DataType.EmailAddress)]
    public string EmailAddress { get; set; }

    [AllowHtml]
    [DataType(DataType.Html)]
    public string Html { get; set; }

    [AllowHtml]
    [DataType(DataType.Text)]
    public string Text { get; set; }

    [DataType(DataType.Url)]
    public string Url { get; set; }

    public bool Boolean { get; set; }

    public bool? TriState { get; set; }

    public decimal Decimal { get; set; }
}

あまり知られていない気がする DataType 属性を使って意味付けを行います。これで文字列でも HTML なのかテキストなのか URL なのか判別が可能になるわけです。

後はスキャフォールディングでコントローラとビューを自動で作ります。そして適当にフォームからデータを登録してみたのが以下の図です。右側は実際に登録した値。

メールアドレスと URL が自動でリンクになっていますね。

他には Html を指定したプロパティはタグが有効になっているのに対して、Text を指定したプロパティはタグがエスケープされています。まだまだ bool が無効状態のチェックボックスだったり、Nullable はドロップダウンだったりいろいろです。

特に追加のコードを書くことなく、デフォルトでここまでのテンプレートを用意してくれるのは非常に便利ですね。

EditorFor

以下の型に対してデフォルトのテンプレートを持っています。

  • 隠しフィールド
  • 複数行テキスト
  • パスワード
  • テキスト
  • コレクション
  • bool
  • decimal
  • string
  • object

string や object は DisplayFor の時と同じく変わり映えのないテキストボックスです。またもコレクションはいまいち使いどころが…。なのでそれ以外のテンプレートを試してみます。

用意したモデルクラスはこんな感じ。これまた単純ですね。

public class EditorModel
{
    public int Id { get; set; }

    [DataType(DataType.MultilineText)]
    public string MultilineText { get; set; }

    [DataType(DataType.Password)]
    public string Password { get; set; }

    [DataType(DataType.Text)]
    public string Text { get; set; }

    public bool Boolean { get; set; }

    public bool? TriState { get; set; }

    public decimal Decimal { get; set; }
}

ここでも同じように DataType を使って意味付けを行います。実は DataType には他にも種類がありますが、MVC が対応していないので指定しても何も起こりません。

そして同様にスキャフォールディングで全部作ります。そして実際に表示してみたのが以下の図です。

MultilineText を指定したプロパティは textarea で表示されていて、Password を指定したプロパティは input type="password" で表示されていますね。他には bool が有効状態のチェックボックス、Nullable が有効状態のドロップダウンで表示されています。

将来的には Date/DateTime を指定すると HTML5 の type="datetime" で出力されたりすると便利そうですね。今でも jQuery UI を使うと type="datetime" を処理できるので、実装して貰いたいですね。

以上、DisplayFor と EditorFor を活用するためにも、モデルクラスには DataType を積極的に付けていった方がいいと思います。DataType は種類が多いので、MVC が対応していなくても付けていた方が理解しやすいと思いますよ。

注意点

これ、DataType ですがメールアドレスや URL などを指定できるので、パッと見はバリデーションまでやってくれそうな雰囲気ですが、全力で無視するので注意してください。

この辺り上手いこと統合できれば素敵だと思うんですがねぇ…。MvcFutures には EmailAddress や Url のバリデータ入ってるので二重になるし…。