ASP.NET MVC - 模型繫結(Model Binding)6大建議

原文:http://www.squidoo.com/asp-net-mvc-model-binding-tips
简中:http://www.cnblogs.com/waw/archive/2011/09/15/2177938.html
無意在網路上看到這篇「ASP.NET MVC Model Binding Tips」,正體中文我翻譯為「ASP.NET MVC 模型繫結6大建議」,簡體中文「ASP.NET MVC模型绑定的6个建议」。

我覺得內容不錯,整理成重點筆記,就內容上在增加一些內容,讓文章意思更清楚些。

Model Binding 重點一:使用 Model Binding


在 ASP.NET MVC 中,應該使用 Model Binding 而不是 Request.Form 來取得資料。早期使用 ASP / ASP.NET,使用 Request.Form() 來取得 Client 所傳送過來的資料是很正常的,但你已經開始使用 MVC 就不應該回頭去使用 Request.Form()。在 ASP.NET MVC 之中應該使用 FormCollection 或直接對物件來進行 Model Binding。

先定義一個簡單的資料物件,Blog.vb,

Public Class Blog
    Public Property Title() As String 
    Public Property PostedOn() As DateTime 
    Public Property Tags() As String 
    Public Property Content() As String 
End Class

內容很簡單,標題、發佈日期、標籤、內容。

在 Controller 裡我想取得 Title 資料。

Public Class HomeController
    Inherits System.Web.Mvc.Controller

    ' 使用 FormCollection 來取的表單資料
    Function Index(form As FormCollection ) As ActionResult
        ViewData("Message") = "歡迎使用 ASP.NET MVC!"
        ViewBag.Title = form("Title")
        Return View()
    End Function

    ' 使用 Model Binding
    Function About(blog As Blog) As ActionResult
        ViewBag.Title = blog.Title 
        Return View()
    End Function
End Class

我還可以使用「黑、白名稱」來過濾不必要的資訊。

Public Class HomeController
    Inherits System.Web.Mvc.Controller

    ' Exclude 等於黑名單
    Function Index(<bind(exclude:="postedon,tags,content")> 
                   form As FormCollection ) As ActionResult
        ViewData("Message") = "歡迎使用 ASP.NET MVC!"
        ViewBag.Title = form("Title")
        Return View()
    End Function

    ' Include 等於白名單
    Function About(<bind(include:="title")> 
                   blog As Blog) As ActionResult
        ViewBag.Title = blog.Title 
        Return View()
    End Function
End Class

取得資料後,我們還能對資料的正確性進處驗證。

' Include 等於白名單
Function About(<bind(include:="title")>
               blog As Blog) As ActionResult
    ViewBag.Title = blog.Title

    ' 資料的正確性
    If Not ModelState.IsValid AndAlso TryUpdateModel(blog) Then
        ' 正確,進行處理
    Else
        ' 錯誤
        ModelState.AddModelError("Title", "ErrorMessage")
    End If
    Return View()
End Function

重點一參考資料



Model Binding 重點二:使用 IModelBinder 介面

IModelBinder 介面:定義模型繫結器所需的方法。(Defines the methods that are required for a model binder.)
它只定義了一個 BindModel 方法:

' 宣告
Function BindModel ( _
	controllerContext As ControllerContext, _
	bindingContext As ModelBindingContext _
) As Object

' BindModel範例
Dim instance As IModelBinder
' 控制器內容
Dim controllerContext As ControllerContext
' 繫結內容
Dim bindingContext As ModelBindingContext
Dim returnValue As Object

returnValue = instance.BindModel(controllerContext, _
	bindingContext)

重點二參考資料

  1. Scott Hanselman - Splitting DateTime - Unit Testing ASP.NET MVC Custom Model Binders
  2. ASP.NET MVC CRUD之路 (3) Decimal Binding問題及ModelBinder擴充應用 (推薦)
在參考資料第二篇理,你可以看到一個完整 IModelBinder 完整實作與應用。

Model Binding重點三:透過繼承(Inheritance)來自訂Model Binding

如果你決定實作一個自訂 Model Binding,想要繼承 DefaultModelBinder 類別來減少工作量,你會發現無法繼承 DefaultModelBinder 類別來達到目的。

重點三參考資料

Model Binding重點四:使用 DataAnnotations 來驗證資料
請先參考「Brad Wilson- DataAnnotations and ASP.NET MVC」。使用起來也很簡單,以前面 Blog.vb 模型來說:

Imports System.ComponentModel.DataAnnotations 

Public Class Blog
    <Required(ErrorMessage:="標題不得空白!")>
    <DataType(datatype.Text)>
    <StringLength(50,ErrorMessage:="標題最大長度只能 50 個字!")>
    Public Property Title() As String

    <Required(ErrorMessage:="日期不得空白!")>
    <DataType(datatype.DateTime)>
    Public Property PostedOn() As DateTime 

    <Required(ErrorMessage:="最少輸入一個標籤分類!")>
    <DataType(datatype.Text)>
    <StringLength(250, ErrorMessage:="標籤最大長度只能 250 個字!")>
    Public Property Tags() As String 

    <Required(ErrorMessage:="內容不得空白!")>
    <DataType(datatype.MultilineText)>
    <StringLength(4000,ErrorMessage:="內容長度需介於 10 ~ 4000 個字!",MinimumLength:=10)>
    <AllowHtml()>
    Public Property Content() As String 
End Class

先引用「Imports System.ComponentModel.DataAnnotations」,然後依你需要的條件,一一設定上去即可。ASP.NET MVC 3會預設自動幫你啟用前端(Javascript)與後端的驗證工作。

Model Binding重點五:Binding與Validation是兩個階段

Binding是取得資料,然後賦予模型的過程;驗證是檢查模型裡的資料。這完全是不同的運作,但 Model Binding 模糊了他們兩個的區別。可以參考:Steve Michelotti - Enterprise Library Validation Application Block with MVC Binders

Model Binding重點六:關於Binding的環境

我們沒有限制數居的來源。可以參考「Scott Hanselman - IPrincipal (User) ModelBinder in ASP.NET MVC for easier testing

以上內容,有些簡單,有些進一步閱讀其他資料。

參考資料


沒有留言:

張貼留言

感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。