2016年12月24日土曜日

ASP.NET MVC 12_テンプレートヘルパー ~その2
DataType属性、DisplayFormat属性

VisualStuidioCommunity2015/Fw4.5.2/C#


DisplayForヘルパーはモデルの値を表示形式で出力します。
EditorForヘルパーはモデルの値を入力形式で出力します。
モデルの値の型やDataType属性に指定した値により出力形式が変わります。

DataType属性による DisplayForヘルパー/ EditorForヘルパー の出力の違い

前回はモデルの値の型(sring型、int型、long型、decimal型、DateTime型、bool型、bool?型、列挙型)による出力の違いをみました。
今回はDataType属性(名前空間:System.ComponentModel.DataAnnotations)による出力の違いをみたいと思います。

DataType.Text

DisplayForヘルパーでの出力は、モデルの値がそのまま出力されるだけで、DataType属性の影響はありません。
EditorForヘルパーでは、モデルの値がint型の場合は<input type="number" >と出力さるところ、DataType.Text属性を付けると<input type="text" >と出力されます。

モデル
using System.ComponentModel.DataAnnotations;

public class AttributeModel
{
    [Display(Name = "int型(DataType.Text)")]
    [DataType(DataType.Text)]
    public int IntValue { get; set; }
}
コントローラー
public ActionResult AttributeAction()
{
    var mdl = new Models.AttributeModel();
    mdl.IntValue = 123456789;
    return View(mdl);
}
ビュー
@model Practice.Models.AttributeModel

<dl>
    <dt>@Html.DisplayNameFor(mdl => mdl.IntValue)</dt>
    <dd>@Html.DisplayFor(mdl => mdl.IntValue)</dd>
    <dd>@Html.EditorFor(mdl => mdl.IntValue)</dd>
</dl>
出力
<dl>
    <dt>int型(DataType.Text)</dt>
    <dd>123456789</dd>
    <dd><input class="text-box single-line" data-val="true" 
     data-val-number="フィールド int型(DataType.Text) には数字を指定してください。" 
     data-val-required="int型(DataType.Text) フィールドが必要です。" 
     id="IntValue" name="IntValue" type="text" value="123456789" /></dd>
</dl>

DataType.Html

DisplayForヘルパーでの出力は通常HTMLエンコードされて出力されますが、DataType.Html属性をつけるとエンコードされずに出力されます。
EditorForヘルパーでの出力には、DataType属性の影響はありません。

モデル
using System.ComponentModel.DataAnnotations;

public class AttributeModel
{
    [Display(Name = "string型(DataType.Html)")]
    [DataType(DataType.Html)]
    public string HtmlValue { get; set; }
}
コントローラー
public ActionResult AttributeAction()
{
    var mdl = new Models.AttributeModel();
    mdl.HtmlValue = "<font color='red'>赤字</font>";
    return View(mdl);
}
ビュー
@model Practice.Models.AttributeModel

<dl>
    <dt>@Html.DisplayNameFor(mdl => mdl.HtmlValue)</dt>   
    <dd>@Html.DisplayFor(mdl => mdl.HtmlValue)</dd>
    <dd>@Html.EditorFor(mdl => mdl.HtmlValue)</dd>
</dl>
出力
<dl>
    <dt>string型(DataType.Html)</dt>   
    <dd><font color='red'>赤字</font></dd>
    <dd><input class="text-box single-line" id="HtmlValue" name="HtmlValue" type="text" 
        value="&lt;font color=&#39;red&#39;&t;赤字&lt;/font&gt;" /></dd>
</dl>

DataType.MultilineText

DisplayForヘルパーでの出力には影響がありません。
EditorForヘルパーでの出力では、テキストエリアが出力されます。

モデル
using System.ComponentModel.DataAnnotations;

public class AttributeModel
{
    [Display(Name = "string型(DataType.MultilineText)")]
    [DataType(DataType.MultilineText)]
    public string MultilineTextValue { get; set; }
}
コントローラー
public ActionResult AttributeAction()
{
    var mdl = new Models.AttributeModel();
    mdl.MultilineTextValue = "1行目\r\n2行目";
    return View(mdl);
}
ビュー
@model Practice.Models.AttributeModel

<dl>
    <dt>@Html.DisplayNameFor(mdl => mdl.MultilineTextValue)</dt>
    <dd>@Html.DisplayFor(mdl => mdl.MultilineTextValue)</dd>
    <dd>@Html.EditorFor(mdl => mdl.MultilineTextValue)</dd>
</dl>

出力
<dl>
<dt>string型(DataType.MultilineText)</dt>
        <dd>1行目
            2行目</dd>
        <dd><textarea class="text-box multi-line" id="MultilineTextValue" 
        name="MultilineTextValue">
        1行目
        2行目</textarea></dd>
</dl>

DataType.EmailAddress

DisplayForヘルパーではメールリンク(<a href="mailto:~">)が出力されます。
EditorForヘルパーではテキストボックス(<input type="email" >)が出力されます。

モデル
using System.ComponentModel.DataAnnotations;

public class AttributeModel
{
 [Display(Name = "string型(DataType.EmailAddress)")]
 [DataType(DataType.EmailAddress)]
 public string EmailAddressValue { get; set; }
}
コントローラー
public ActionResult AttributeAction()
{
    var mdl = new Models.AttributeModel();
    mdl.EmailAddressValue = "aaa@gmail.com";
    return View(mdl);
}
ビュー
@model Practice.Models.AttributeModel

<dl>
    <dt>@Html.DisplayNameFor(mdl => mdl.MultilineTextValue)</dt>
    <dd>@Html.DisplayFor(mdl => mdl.MultilineTextValue)</dd>
    <dd>@Html.EditorFor(mdl => mdl.MultilineTextValue)</dd>
</dl>

出力
<dl>
    <dt>string型(DataType.EmailAddress)</dt>
    <dd><a href="mailto:aaa@gmail.com">aaa@gmail.com</a></dd>
    <dd><input class="text-box single-line" id="EmailAddressValue" 
        name="EmailAddressValue" type="email" value="aaa@gmail.com" /></dd>
</dl>

DataType.Url

DisplayForヘルパーではハイパーリンク(<a href="~">)が出力されます。
EditorForヘルパーではテキストボックス(<input type="url" >)が出力されます。

モデル
using System.ComponentModel.DataAnnotations;

public class AttributeModel
{
    [Display(Name = "string型(DataType.Url)")]
    [DataType(DataType.Url)]
    public string UrlValue { get; set; }
}
コントローラー
public ActionResult AttributeAction()
{
    var mdl = new Models.AttributeModel();
    mdl.UrlValue = "https://www.google.co.jp";
    return View(mdl);
}
ビュー
@model Practice.Models.AttributeModel

<dl>
    <dt>@Html.DisplayNameFor(mdl => mdl.UrlValue)</dt>
        <dd>@Html.DisplayFor(mdl => mdl.UrlValue)</dd>
        <dd>@Html.EditorFor(mdl => mdl.UrlValue)</dd>
</dl>

出力
<dl>
<dt>string型(DataType.Url)</dt>
        <dd><a href="https://www.google.co.jp">https://www.google.co.jp</a></dd>
        <dd><input class="text-box single-line" id="UrlValue" name="UrlValue" type="url" value="https://www.google.co.jp" /></dd>
</dl>

DataType.Password

DisplayForヘルパーでの出力には影響がありません。
EditorForヘルパーではテキストボックス(<input type="password" >)が出力されます。

モデル
using System.ComponentModel.DataAnnotations;

public class AttributeModel
{
        [Display(Name = "string型(DataType.Password)")]
        [DataType(DataType.Password )]
        public string PasswordValue { get; set; }
}
コントローラー
public ActionResult AttributeAction()
{
    var mdl = new Models.AttributeModel();
    mdl.PasswordValue  = "ABCD123";
    return View(mdl);
}
ビュー
@model Practice.Models.AttributeModel

<dl>
    <dt>@Html.DisplayNameFor(mdl => mdl.PasswordValue)</dt>
        <dd>@Html.DisplayFor(mdl => mdl.PasswordValue)</dd>
        <dd>@Html.EditorFor(mdl => mdl.PasswordValue)</dd>
</dl>

出力
<dl>
 <dt>string型(DataType.Password)</dt>
        <dd>ABCD123</dd>
        <dd><input class="text-box single-line password" id="PasswordValue" name="PasswordValue" type="password" value="ABCD123" /></dd>
</dl>

DataType.PhoneNumber

DisplayForヘルパーでの出力には影響がありません。
EditorForヘルパーではテキストボックス(<input type="tel" >)が出力されます。

モデル
using System.ComponentModel.DataAnnotations;

public class AttributeModel
{
        [Display(Name = "string型(DataType.PhoneNumber)")]
        [DataType(DataType.PhoneNumber )]
        public string PhoneNumberValue { get; set; }
}
コントローラー
public ActionResult AttributeAction()
{
    var mdl = new Models.AttributeModel();
    mdl.PhoneNumberValue  = "09012345678";
    return View(mdl);
}
ビュー
@model Practice.Models.AttributeModel

<dl>
    <dt>@Html.DisplayNameFor(mdl => mdl.PhoneNumberValue)</dt>
    <dd>@Html.DisplayFor(mdl => mdl.PhoneNumberValue)</dd>
    <dd>@Html.EditorFor(mdl => mdl.PhoneNumberValue)</dd>
</dl>

出力
<dl>
    <dt>string型(DataType.PhoneNumber)</dt>
    <dd>09012345678</dd>
    <dd><input class="text-box single-line" id="PhoneNumberValue" name="PhoneNumberValue" type="tel" value="09012345678" /></dd>
</dl>

DataType.DateTime、DataType.Date、DataType.Time

DisplayForヘルパーではDataType.DateTimeでは年月日時分秒が出力され、DataType.Dateでは年月日が、DataType.Timeでは時分が出力されます。
EditorForヘルパーではそれぞれにテキストボックス(<input type="datetime" >、<input type="date" >、<input type="time" >)が出力されます。

DataType.Date、DateType.TimeではEditorForで値が出力されていません。
後述のDataFormat属性をつけると出力されます。

モデル
using System.ComponentModel.DataAnnotations;

public class AttributeModel
{
    [DataType(DataType.DateTime)]
    public DateTime DateTimeValue { get; set; }

    [Display(Name = "DateTime(DataType.Date)")]
    [DataType(DataType.Date)]
    public DateTime DateValue { get; set; }

    [Display(Name = "DateTime(DataType.Time)")]
    [DataType(DataType.Time)]
    public DateTime TimeValue { get; set; }}
コントローラー
public ActionResult AttributeAction()
{
    var mdl = new Models.AttributeModel();
    mdl.DateTimeValue = DateTime.Now;
    mdl.DateValue = DateTime.Now;
    mdl.TimeValue = DateTime.Now;
    return View(mdl);
}
ビュー
@model Practice.Models.AttributeModel

<dl>
    <dt>@Html.DisplayNameFor(mdl => mdl.DateTimeValue)</dt>
    <dd>@Html.DisplayFor(mdl => mdl.DateTimeValue)</dd>
    <dd>@Html.EditorFor(mdl => mdl.DateTimeValue)</dd>

    <dt>@Html.DisplayNameFor(mdl => mdl.DateValue)</dt>
    <dd>@Html.DisplayFor(mdl => mdl.DateValue)</dd>
    <dd>@Html.EditorFor(mdl => mdl.DateValue)</dd>

    <dt>@Html.DisplayNameFor(mdl => mdl.TimeValue)</dt>
    <dd>@Html.DisplayFor(mdl => mdl.TimeValue)</dd>
    <dd>@Html.EditorFor(mdl => mdl.TimeValue)</dd>
</dl>

出力
<dl>
    <dt>DateTime(DataType.DateTme)</dt>
    <dd>2016/12/23 6:11:56</dd>
    <dd><input class="text-box single-line" data-val="true" 
        data-val-date="フィールド DateTime(DataType.DateTme) は日付である必要があります。" 
        data-val-required="DateTime(DataType.DateTme) フィールドが必要です。" 
        id="DateTimeValue" name="DateTimeValue" type="datetime" value="2016/12/23 6:11:56" /></dd>

    <dt>DateTime(DataType.Date)</dt>
    <dd>2016/12/23</dd>
    <dd><input class="text-box single-line" 
        data-val="true" data-val-date="フィールド DateTime(DataType.Date) は日付である必要があります。" 
        data-val-required="DateTime(DataType.Date) フィールドが必要です。" 
        id="DateValue" name="DateValue" type="date" value="2016/12/23" /></dd>

    <dt>DateTime(DataType.Time)</dt>
    <dd>6:11</dd>
    <dd><input class="text-box single-line" 
        data-val="true" data-val-required="DateTime(DataType.Time) フィールドが必要です。" 
        id="TimeValue" name="TimeValue" type="time" value="6:11" /></dd>
</dl>

先ほどDataType属性でDataType.DateやDateType.Timeを指定すると、EditorForで出力されたテキストボックスに値が出力されていませんでした。
これはDataFormat属性(名前空間:System.ComponentModel.DataAnnotations)で書式設定方法を指定すると出力されるようになります。


DisplayFormat属性のDataFormatStringプロパティに書式文字列を設定します。
ApplyFormatInEditModeプロパティには編集時にも書式を適用する場合にtrueを設定します。
DisplayFormat属性には他にもプロパティがあります。(後述のまとめ参照)

しかし、DateType.Dateの場合は編集時の書式が「yyyy-MM-dd」ではなく「yyyy/MM/dd」になっています。
ためしに書式を「{0:yyyy年MM月dd日}」としたところ、やはり値が出力されませんでした。
chrome(バージョン:55.0.2883.87)では<intput type="date" >の要素にフォーカスすると、カレンダーが表示されますが、おそらくこのカレンダーが「/」しか対応していないのではないでしょうか。

モデル
using System.ComponentModel.DataAnnotations;

public class AttributeModel
{
    [DataType(DataType.DateTime)]
    [DisplayFormat(DataFormatString = "{0:yy年MM月dd日}", ApplyFormatInEditMode = true)]
    public DateTime DateTimeValue { get; set; }

    [Display(Name = "DateTime(DataType.Date)")]
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    public DateTime DateValue { get; set; }

    [Display(Name = "DateTime(DataType.Time)")]
    [DataType(DataType.Time)]
    [DisplayFormat(DataFormatString = "{0:HH:mm}", ApplyFormatInEditMode = true)]
    public DateTime TimeValue { get; set; }
}

DataType.Currency

DataType.Currencyの場合、カレントカルチャ情報に合わせた出力がされます。
DisplayForヘルパーでは、カレントカルチャの通貨情報でフォーマットされ出力されました。
EditorForヘルパーではカレントカルチャの数値情報でフォーマットされ、テキストボックス(<input type="text" >)で出力されました。

モデル
using System.ComponentModel.DataAnnotations;

public class AttributeModel
{
    [Display(Name = "Decimal(DataType.Currency)")]
    [DataType(DataType.Currency)]
    public Decimal CurrencyValue { get; set; }
}
コントローラー
public ActionResult AttributeAction()
{
    var mdl = new Models.AttributeModel();
    mdl.CurrencyValue = 12345678.5678m;
    return View(mdl);
}
ビュー
@model Practice.Models.AttributeModel

<dl>
    <dt>@Html.DisplayNameFor(mdl => mdl.CurrencyValue)</dt>
    <dd>@Html.DisplayFor(mdl => mdl.CurrencyValue)</dd>
    <dd>@Html.EditorFor(mdl => mdl.CurrencyValue)</dd>
</dl>

出力
<dl>
    <dt>Decimal(DataType.Currency)</dt>
    <dd>¥12,345,679</dd>
    <dd><input class="text-box single-line" data-val="true" 
        data-val-number="フィールド Decimal(DataType.Currency) には数字を指定してください。" 
        data-val-required="Decimal(DataType.Currency) フィールドが必要です。" 
        id="CurrencyValue" name="CurrencyValue" type="text" value="12345678.57" /></dd>
</dl>



まとめ

主なDataType属性
DataTypeDisplaryForヘルパーEditorForヘルパー
DataType.Textテキストボックス
<input type="text" >
DataType.Html値をエンコードせずに出力するテキストボックス
<input type="text" >
DataType.MultilineTextテキストエリア
<textarea>
DataType.EmailAddressメールリンク
<a href="mailto:~">
テキストボックス
<input type="email" >
DataType.Urlハイパーリンク
<a href="~">
テキストボックス
<input type="url" >
DataType.Passwordテキストボックス
<input type="password" >
DataType.PhoneNumber テキストボックス
<input type="tel" >
DataType.DateTime年月日時分秒が出力されるテキストボックス
<input type="datetime" >
DataType.Date年月日が出力されるテキストボックス
<input type="date" >
DataType.Time時分が出力されるテキストボックス
<input type="time" >
DataType.Currencyカレントカルチャの金額情報でフォーマットされ出力されるカレントカルチャの数値情報でフォーマットされ出力される
<input type="time" >

DisplayFormat属性
DateFormatString書式文字列
ApplyFormatInEditMode編集時にも書式を適用するかどうか
ConvertEmptyStringToNull空文字列をnullに変換するかどうか
NullDisplayText値がnullの時に表示するテキスト

0 件のコメント: