Metadata的使用

 

於Model的類別檔新增Metadata,但請注意使用Metadata前必先Include System.ComponentModel.DataAnnotations元件,

System.ComponentModel.DataAnnotations底下提供了很多可用的驗證類別,

例如:Required、DataType、Password等類別,

而每個驗證類別通常有共通的ErrorMessage、RequiresValidationContext等屬性;

也另提供資料欄位格式化屬性,例如:DisplayFormat。

 

一、前置準備

Model部分

using System.ComponentModel.DataAnnotations;

namespace WebApplication2.Models
{
    public class Class1
    {
        public string id { get; set; }
        public string name { get; set; }
    }
}

Controller部分

using System.Collections.Generic;
using System.Web.Mvc;
using WebApplication2.Models;

namespace WebApplication2.Controllers
{
    public class HomeController : Controller
    {
        public List<Class1> db = null;
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Create()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Create(Class1 Class1)
        {
            if (ModelState.IsValid)
            {
                db.Add(Class1);
                return RedirectToAction("Index");
            }

            return View(Class1);
        }
    }
}

View部分-Create.cshtml

@model WebApplication2.Models.Class1

@using (Html.BeginForm())
{
    <input type="text" name="id" value="" />
    @Html.ValidationMessageFor(model => model.id, "", new { @class = "text-danger" })
    <br />
    <input type="text" name="name" value="" />
    @Html.ValidationMessageFor(model => model.name, "", new { @class = "text-danger" })
    <br />
    <input type="submit" value="Create" />
}

 

二、Matadata的使用

1、Required類別

判斷式類別,功用為指出哪一個資料欄位為必填。

藉由上面的準備範例我們於Model的Class1對id屬性加上Metadata [Required],

Create.cshtml起始畫面

由於已限定id欄位為必填,所以我們直接按Create按鈕,看看結果如何

由上畫面可知id欄位沒填入資料將會被檢測出來。

注意,Matadata在前端會跟ValidationMessageFor配合,然後秀出有問題的訊息,

而後端則是利用「ModelState.IsValid」來做判斷。

 

2、MaxLength類別

判斷式類別,此功能顧名思義為驗證該欄位的最大字數不應超過n個字,

注意,一定要指定MaxLength類別的Length屬性,否則無作用。

MaxLength類別的建構子的形式範例可為

[MaxLength(2)]、

[MaxLength(length: 2)]

還可以指定ErrorMessage如下

[MaxLength(length: 2,ErrorMessage="happend a Error")]。

畫面執行前

執行後結果

 

3、Range類別與格式化錯誤訊息

判斷式類別,功用為於Model的id屬性添加metadata [Range(0, 10)]

using System.ComponentModel.DataAnnotations;

namespace WebApplication2.Models
{
    public class Class1
    {
        [Range(0, 10)]
        public string id { get; set; }        
        public string name { get; set; }
    }
}

Controller與View都維持範例不變

執行結果如下

如果於metadata再加上自訂的ErrorMessage的話,

於Model的id屬性添加metadata [Range(0, 10, ErrorMessage = "{0}的範圍介於{1}到{2}之間")]

則執行結果為

 

4、DisplayFormat類別

顯示式類別,功用為用來對欄位格式化,可用的屬性有

(1)、DataFormatString

我以時間欄位為例子,於Model改成

using System.ComponentModel.DataAnnotations;

namespace WebApplication2.Models
{
    public class Class1
    {   
        public string id { get; set; }
        [DisplayFormat(DataFormatString = "{0:MM-dd-yyyy}")]
        public System.DateTime name { get; set; }
    }
}

既然是對時間欄位格式化,則欄位型態記得使用System.DateTime。

Controller的Create action則使用

using System.Collections.Generic;
using System.Web.Mvc;
using WebApplication2.Models;

namespace WebApplication2.Controllers
{
    public class HomeController : Controller
    {
        public List<Class1> db = null;
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Create()
        {
            Class1 Class1 = new Class1();
            Class1.name = System.DateTime.Now;
            return View(Class1);
        }

        [HttpPost]
        public ActionResult Create(Class1 Class1)
        {
            if (ModelState.IsValid)
            {
                db.Add(Class1);
                return RedirectToAction("Index");
            }

            return View(Class1);
        }
    }
}

View的Create.cshtml則使用DisplayFor方法

@model WebApplication2.Models.Class1
@using (Html.BeginForm())
{
    <input type="text" name="id" value="" />
    @Html.ValidationMessageFor(model => model.id, "", new { @class = "text-danger" })
    <br />
    @Html.DisplayFor(m => m.name)
    @Html.ValidationMessageFor(model => model.name, "", new { @class = "text-danger" })
    <br />
    @Html.EditorFor(m => m.name)
    @Html.ValidationMessageFor(model => model.name, "", new { @class = "text-danger" })
    <br />
    <input type="submit" value="Create" />
}

畫面為

由上可知DisplayFormat類別專門跟DisplayFor方法配合的;對於EditorFor方法則無作用。

DisplayFormat類別除了最常用的DataFormatString屬性之外,

還有[ApplyFormatInEditMode = bool ]、[ConvertEmptyStringToNull = bool]、

[HtmlEncode = bool]、[NullDisplayText = string]四種非常實用的屬性可一起套用,

如:[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]

 

5、DataType類別

顯示式類別,有多種列舉,請參閱DataType Enumeration

Member name Description
CreditCard Represents a credit card number.
Currency Represents a currency value.
Custom Represents a custom data type.
Date Represents a date value.
DateTime Represents an instant in time, expressed as a date and time of day.
Duration Represents a continuous time during which an object exists.
EmailAddress Represents an e-mail address.
Html Represents an HTML file.
ImageUrl Represents a URL to an image.
MultilineText Represents multi-line text.
Password Represent a password value.
PhoneNumber Represents a phone number value.
PostalCode Represents a postal code.
Text Represents text that is displayed.
Time Represents a time value.
Upload Represents file upload data type.
Url Represents a URL value.

 

(1)、DataType.Date列舉

於Model的name屬性添加metadata [DataType(DataType.Date)]

將Create.cshtml改為

@model WebApplication2.Models.Class1
@using (Html.BeginForm())
{
    <input type="text" name="id" value="" />
    @Html.ValidationMessageFor(model => model.id, "", new { @class = "text-danger" })
    <br />
    @Html.EditorFor(m => m.name)
    @Html.ValidationMessageFor(model => model.name, "", new { @class = "text-danger" })
    <br />
    <input type="submit" value="Create" />
}

執行畫面為

而又於Controller的Create action改成讓Create頁面於一開始載入預設值

using System.Collections.Generic;
using System.Web.Mvc;
using WebApplication2.Models;

namespace WebApplication2.Controllers
{
    public class HomeController : Controller
    {
        public List<Class1> db = null;
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Create()
        {
            Class1 Class1 = new Class1();
            Class1.name = "2016-11-02";
            return View(Class1);
        }

        [HttpPost]
        public ActionResult Create(Class1 Class1)
        {
            if (ModelState.IsValid)
            {
                db.Add(Class1);
                return RedirectToAction("Index");
            }

            return View(Class1);
        }
    }
}

則可以成功讀取到日期格式

由上範例可知DataType類別專門跟@Html.EditorFor()方法配合的,

用來顯示數值與表現出相對應的格式。

其主要目的就是幫你生成下面的Html原始碼

<input type="date" name="id" value="" />

 

(2)、DataType.Password列舉

於Model的name屬性添加metadata [DataType(DataType.Password)]

View方面也是跟EditorFor方法配合,將Create.cshtml改為

@model WebApplication2.Models.Class1
@using (Html.BeginForm())
{
    <input type="text" name="id" value="" />
    @Html.ValidationMessageFor(model => model.id, "", new { @class = "text-danger" })
    <br />
    @Html.EditorFor(m => m.name)
    @Html.ValidationMessageFor(model => model.name, "", new { @class = "text-danger" })
    <br />
    <input type="submit" value="Create" />
}

操作的畫面如下

其主要目的就是幫你生成下面的Html原始碼

<input type="password" name="id" value="" />

 

6、DisplayAttribute類別

Model為

using System.ComponentModel.DataAnnotations;

namespace WebApplication2.Models
{
    public class Class1
    {
        public string id { get; set; }
        [Display(Name = "活動名稱")]
        public string name { get; set; }
    }
}

 

Controller為

using System.Collections.Generic;
using System.Web.Mvc;
using WebApplication2.Models;

namespace WebApplication2.Controllers
{
    public class HomeController : Controller
    {
        public List<Class1> db = null;
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Create()
        {
            Class1 Class1 = new Class1();
            Class1.name = "brooke";
            return View(Class1);
        }

        [HttpPost]
        public ActionResult Create(Class1 Class1)
        {
            if (ModelState.IsValid)
            {
                db.Add(Class1);
                return RedirectToAction("Index");
            }

            return View(Class1);
        }
    }
}

 

View為

@model WebApplication2.Models.Class1
@using (Html.BeginForm())
{
    <input type="text" name="id" value="" />
    @Html.ValidationMessageFor(model => model.id, "", new { @class = "text-danger" })
    <br />
    @Html.DisplayFor(m => m.name)
    @Html.ValidationMessageFor(model => model.name, "", new { @class = "text-danger" })
    <br />
    @Html.EditorFor(m => m.name)
    @Html.ValidationMessageFor(model => model.name, "", new { @class = "text-danger" })
    <br />
    @Html.DisplayNameFor(m => m.name)
    @Html.ValidationMessageFor(model => model.name, "", new { @class = "text-danger" })
    <br />
    <input type="submit" value="Create" />
}

 

畫面為

由此可知,可藉由在model端使用DisplayAttribute類別來改變前端所顯示的欄位名稱。

特別注意,DisplayAttribute類別只在DisplayNameFor方法有作用。

開發者可能會以為是使用DisplayColumnAttribute類別,

就可以改變前端所顯示的欄位名稱,其實是有問題的,這可能會搞混,要特別注意。

 

參考資料:

System.ComponentModel.DataAnnotations 命名空間

DisplayFormatAttribute 類別

DisplayFormatAttribute.DataFormatString 屬性

DynamicField 類別

.NET Framework 中的格式化類型簡述