2.6 繫結資料模型

ASP.NET MVC 實務精要|第二章 表單

實際的開發應用上,調用HtmlHelper方法產生input元素時,通常不會直接指定固定的值,而是透過模型資料繫結進行設定,於執行期間動態載入資料,為了方便說明,現在建立另外一個ModelDemo專案,新增一個Book資料類別,用以封裝所要處理的書籍資訊,並且設計內容如下:。

public class Book
{
public int Id { get; set; }
public string Title { get; set; }
    public string Author { get; set; }
    public int Price { get; set; }
}

於Controller資料夾新增一個空白的Home控制器HomeController.cs,並於其中建立一個Detail動作方法,新增如下的內容:

public ActionResult Detail()
{
    Book book = new Book {
     Id = 1001,
     Title = "ASP.NET MVC 實務精要",
     Author = "Sean",
     Price = 880 };
    return View(book);
}

這個動作方法在被呼叫時,建立一個新的Book類別物件並且將其當作參數回傳至檢視檔案。建立此控制器動作方法的關聯檢視檔案,並且輸入以下的內容:

@model ModelDemo.Models.Book
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Detail</title>
</head>
<body>
    <div>
<p>@Html.Label("Id") @Html.TextBox("Id")  </p>
        <p>@Html.Label("Title") @Html.TextBox("Title") </p>
        <p>@Html.Label("Author") @Html.TextBox("Author") </p>
        <p>@Html.Label("Price") @Html.TextBox("Price")</p>   
</div>
</body>
</html>

其中引用的Helper方法,並分別指定對應的Book類別的屬性名稱,輸出的結果畫面如下:


以Title屬性為例,對應的HTML輸出如下,為了方便說明,以下列表作了適當的斷行。

<p>
<label for="title">Title</label>
<input id="Title" name="Title" type="text" value="ASP.NET MVC 實務精要" />
</p>

當網頁中宣告了某個資料模型類別,只要在Helper方法中指定對應的屬性名稱,則傳送進來的資料會自動配置輸出於對應的元素。以這裏的輸出為例,input 元素中,id與name屬性值直接以Book的Title屬性名稱命名,而value值則是Book的Title屬性值「ASP.NET MVC 實務精要」,其餘原理相同。

要特別注意的是Label方法,它只會輸出你指定的字串對應的Book屬性名稱,而非屬性值,因此文字方塊中顯示的是「ASP.NET MVC 實務精要」,而Label顯示的是「Title」。

如果要自行指定這些值,可以進一步透過兩個參數的多載版本設定所要顯示的內容,現在將其調整如下:

@model ModelDemo.Models.Book
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Detail</title>
</head>
<body>
    <div>
        <p>@Html.Label("編號") @Html.Label("Id",@Model.Id.ToString())  </p>
        <p>@Html.Label("書名") @Html.TextBox("Title", @Model.Title) </p>
        <p>@Html.Label("作者") @Html.TextBox("Author", @Model.Author) </p>
        <p>@Html.Label("價格") @Html.TextBox("Price", @Model.Price)
    </div>
</body>
</html>

第一行宣告表示承接控制器 CBook 動作方法傳送過來的物件模型參數型別為ModelDemo.Models.Book,接下來於網頁中,即可在網頁主體中,逐一取出Book模型的各項屬性值,以編號為例,@Model.Id.ToString() 這一行程式碼中的 Model關鍵字表示傳送過來的Model物件,也就是一開始宣告的 Book型態物件,由於Id是整數進一步將其轉換成為字串以方便呈現。

在一般的情形下,通常不會允許使用者異動資料編號,因此Id以Label呈現,第二行開始則是引用TextBox 輸出文字方塊以支援編輯作業,調用第二個多載方法,將第一個參數設定為Book類別對應的屬性名稱,第二個參數則是呈現屬性值,以下列舉輸出畫面。


與上述第一個實作的方式比較,此次Id值是無法修改的唯讀欄位,且以中文輸出標題。

資料顯示-Display

上述討論的資料輸出過程當中,讀者應該發現了Label的問題,當你直接以Label指定對應的Book類別屬性名稱-例如Ttitle,不同於TextBox,它並不會顯示對應的資料內容,再看一次以下的配置:

<p>@Html.Label("Title") @Html.TextBox("Title") </p>

其中的Label最後顯示的結果依然是Title這個字串,而TextBox顯示的值則是Book類別的Title屬性值「ASP.NET MVC 實務精要」,為了顯示唯讀的資料內容,例如上述的id,只能透過Label引用兩個參數的多載版本如下:

@Html.Label("id",@Model.Id.ToString())

事實上,如果要在網頁上以唯讀形式輸出模型屬性資料,只需引用Display即可,例如以下的配置:

@Html.Display("id")

這一行程式碼會將id屬性的值1001直接輸出於網頁,並且不產生任何標籤,如果你要提供一個單純顯示資料內容的網頁,只要以Display取代Label或是TextBox即可。


沒有留言: