2016年12月18日日曜日

ASP.NET MVC 12_テンプレートヘルパー ~その1~

VisualStuidioCommunity2015/Fw4.5.2/C#


前回までは個別のHTMLヘルパーを見てきました。
今回はテンプレートヘルパーを見て行きます。

テンプレートヘルパーは、引数に指定したモデルのプロパティの型やその属性から自動的にHTML要素を生成してくれます。
たとえばstring型であればinput要素を、bool型であればcheckbox要素を生成するといった具合です。

DisplayNameForヘルパー

DisplayNameForヘルパーは、モデルのプロパティの表示名をhtmlタグで修飾せずに出力します。
属性を指定しない場合、プロパティ名をそのまま出力します。
DisplayName属性を指定した場合、指定した値を出力します。
Display属性のnameプロパティを指定した場合も、指定した値を出力します。

モデル
//DisplayName属性を使用する場合にインポートする
using System.ComponentModel;
//Display属性を使用する場合にインポートする
using System.ComponentModel.DataAnnotations;

namespace Practice.Models
{
    public class TemplateHelperViewModel
    {
        public string Text1 { get; set; }

        [DisplayName("テキスト2")]
        public string Text2 { get; set; }

        [Display(Name = "テキスト3")]
        public string Text3 { get; set; }
    }
}
コントローラー
using System.Web.Mvc;

namespace Practice.Controllers
{
    public class TemplateHelperController : Controller
    {
        public ActionResult Index()
        {
            var mdl = new Models.TemplateHelperViewModel();
            return View(mdl);
        }
    }
}
ビュー
@model Practice.Models.TemplateHelperViewModel

@Html.DisplayNameFor(mdl => mdl.Text1)
@Html.DisplayNameFor(mdl => mdl.Text2)
@Html.DisplayNameFor(mdl => mdl.Text3)

DisplayName属性(名前空間:System.ComponentModel)は、表示名しか指定できませんが、
Display属性(名前空間:System.ComponentModel.DataAnnotations)は、表示名以外にも表示方法をカスタマイズするためのプロパティがあります。
たとえば表示名をリソースファイルから出力するなど、Display属性でなければできない事がありますので、より汎用的なDisplay属性を使用する方がよさそうです。

DisplayForヘルパー/ EditorForヘルパー

DisplayForヘルパーはモデルの値を表示形式で出力します。
EditorForヘルパーはモデルの値を入力形式で出力します。
モデルの値の型やDataType属性(名前空間:System.ComponentModel.DataAnnotations)に指定した値により出力形式が変わります。

モデルの型による出力

まずはモデルの値の型によってどのような出力がされるか見ていきます。
string型、int型、long型、decimal型、DateTime型、bool型、bool?型(Nullable)、列挙型についてみてみます。

モデル
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace Practice.Models
{    
    public enum WeweathereType
    {
        [Display(Name = "晴れ")]
        sunny,
        [Display(Name = "曇")]
        cloudy,
        [Display(Name = "雨")]
        rainy
    }
    
    public class DisplayForViewModel
    {
        [Display(Name ="String型")]
        public string StringValue { get; set; }

        [Display(Name = "int型")]
        public int IntValue { get; set; }

        [Display(Name = "long型")]
        public long LongValue { get; set; }

        [Display(Name = "decimal型")]
        public decimal DecimalValue { get; set; }

        [Display(Name = "DateTime型")]
        public DateTime DateTimeValue { get; set; }

        [Display(Name = "bool型")]
        public bool BoolValue { get; set; }

        [Display(Name = "bool(Nullable)型")]
        public bool? NullableBoolValue { get; set; }

        [Display(Name = "enum型")]
        public WeweathereType EnumValue { get; set; }  
    }
}
コントローラー
using System;
using System.Collections.Generic;
using System.Web.Mvc;

namespace Practice.Controllers
{
    public class TemplateHelperController : Controller
    {
        public ActionResult Index()
        {
            var mdl = new Models.DisplayForViewModel();
            mdl.StringValue = "赤字";
            mdl.IntValue = 123456789;
            mdl.LongValue = 123456789012345;
            mdl.DecimalValue = 12345.99999m;
            mdl.DateTimeValue = new DateTime(2017,01,01);
            mdl.BoolValue = true;
            mdl.NullableBoolValue = true;
            mdl.EnumValue = Models.WeweathereType.rainy;
            return View(mdl);
        }
    }
}
ビュー
@model Practice.Models.Index

@Html.DisplayNameFor(mdl => mdl.StringValue)
@Html.DisplayFor(mdl => mdl.StringValue)
@Html.EditorFor(mdl => mdl.StringValue)
@Html.DisplayNameFor(mdl => mdl.IntValue)
@Html.DisplayFor(mdl => mdl.IntValue)
@Html.EditorFor(mdl => mdl.IntValue)
@Html.DisplayNameFor(mdl => mdl.LongValue)
@Html.DisplayFor(mdl => mdl.LongValue)
@Html.EditorFor(mdl => mdl.LongValue)
@Html.DisplayNameFor(mdl => mdl.DecimalValue)
@Html.DisplayFor(mdl => mdl.DecimalValue)
@Html.EditorFor(mdl => mdl.DecimalValue)
@Html.DisplayNameFor(mdl => mdl.DateTimeValue)
@Html.DisplayFor(mdl => mdl.DateTimeValue)
@Html.EditorFor(mdl => mdl.DateTimeValue)
@Html.DisplayNameFor(mdl => mdl.BoolValue)
@Html.DisplayFor(mdl => mdl.BoolValue)
@Html.EditorFor(mdl => mdl.BoolValue)
@Html.DisplayNameFor(mdl => mdl.NullableBoolValue)
@Html.DisplayFor(mdl => mdl.NullableBoolValue)
@Html.EditorFor(mdl => mdl.NullableBoolValue)
@Html.DisplayNameFor(mdl => mdl.EnumValue)
@Html.DisplayFor(mdl => mdl.EnumValue)
@Html.EditorFor(mdl => mdl.EnumValue)
出力

データ型による出力の違い
データ型DisplayForヘルパーの出力EditorForヘルパーの出力
string型htmlエンコードされて出力されるテキストボックス
<input type="text" >
int型テキストボックス
<input type="number" >
long型テキストボックス
<input type="number" >
decimal型値が丸められて出力されるテキストボックス
<input type="text" >
値が丸められて出力される。
DateTime型テキストボックス
<input type="datetime" >
bool型無効なチェックボックス
<input type="checkbox" disabled="disabled" >
hidden要素は出力されない
チェックボックス型
<input type="checkbox" >
Hidden要素(<input type="hidden" >)が出力される。
bool?型(Nullable)無効なドロップダウン
<select disabled="disabled">
ドロップダウン
<select>
列挙型テキストボックス
<input type="text" >
decimal型は予想に反してtype="text"として出力されました。
bool型はチェックボックスとして、Nullableなbool型はドロップダウンとして出力されます。
enum型はテキストボックスとして表示されましたが、コチラではドロップダウンとして表示されると記載されています。


<dl>
<dt>String型</dt>
        <dd><font color='red'>赤字</font></dd>
        <dd><input class="text-box single-line" id="StringValue" name="StringValue" type="text" 
         value="<font color='red'>赤字</font>" /></dd>
<dt>int型</dd>
        <dd>123456789</dd>
        <dd><input class="text-box single-line" data-val="true" 
         data-val-number="フィールド int型 には数字を指定してください。" 
         data-val-required="int型 フィールドが必要です。" id="IntValue" name="IntValue" 
         type="number" value="123456789" /></dd>
<dt>long型</dd>
        <dd>123456789012345</dd>
        <dd><input class="text-box single-line" data-val="true" 
         data-val-number="フィールド long型 には数字を指定してください。" 
         data-val-required="long型 フィールドが必要です。" 
         id="LongValue" name="LongValue" type="number" value="123456789012345" /></dd>
<dt>decimal型</dd>
        <dd>12346.00</dd>
        <dd><input class="text-box single-line" data-val="true" 
         data-val-number="フィールド decimal型 には数字を指定してください。" 
         data-val-required="decimal型 フィールドが必要です。" 
         id="DecimalValue" name="DecimalValue" type="text" value="12346.00" /></dd>
<dt>DateTime型</dd>
        <dd>2017/01/01 0:00:00</dd>
        <dd><input class="text-box single-line" data-val="true" 
         data-val-date="フィールド DateTime型 は日付である必要があります。" 
         data-val-required="DateTime型 フィールドが必要です。" id="DateTimeValue" 
         name="DateTimeValue" type="datetime" value="2017/01/01 0:00:00" /></dd>
<dt>bool型</dd>
        <dd><input checked="checked" class="check-box" disabled="disabled" 
         type="checkbox" /></dd>
        <dd><input checked="checked" class="check-box" data-val="true" 
         data-val-required="bool型 フィールドが必要です。" id="BoolValue" name="BoolValue" 
         type="checkbox" value="true" />
         <input name="BoolValue" type="hidden" value="false" /></dd>
<dt>bool(Nullable)型</dd>
        <dd><select class="tri-state list-box" disabled="disabled">
         <option value="">設定なし</option>
         <option selected="selected" value="true">True</option>
         <option value="false">False</option>
         </select>
        </dd>
        <dd><select class="list-box tri-state" id="NullableBoolValue" name="NullableBoolValue">
         <option value="">設定なし</option>
   <option selected="selected" value="true">True</option>
   <option value="false">False</option>
   </select>
  </dd>
<dt>enum型</dd>
        <dd>rainy</dd>
        <dd><input class="text-box single-line" data-val="true" 
         data-val-required="enum型 フィールドが必要です。" id="EnumValue" name="EnumValue" 
         type="text" value="rainy" /></dd>
</dl>

0 件のコメント: