1. 程式人生 > >MVC 手寫模型繫結

MVC 手寫模型繫結

使用情景介紹:

首先我們在專案中建立一個Person實體類

namespace MvcApp.Models
{
    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }      
    }
}

建立一個HomeController控制器,然後我們新增一個Index檢視。

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>模型繫結測試</title>
</head>
<body>
    <form action="/Home/PostData" method="post">
        <div>
            編號 <input type="text" name="w_id" />
            姓名 <input type="text" name="w_name" />
            年齡 <input type="text" name="w_age" />

            <input type="submit" value="提交" />
        </div>
    </form>
</body>
</html>

在HomeController下面建立一個PostData方法,在這個方法中我們想用一個Person類來接收從檢視傳過來的表單資料

namespace MvcApp.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }       
        public ActionResult PostData(Person per)
        {

            return View();
        }
    }
}


我們發現這個per物件並不能接收從Index檢視頁面傳遞過來的表單資料(當然如果你將per物件中的屬性名稱改成與檢視提交過來的表單name屬性一致那也是可以接收到從視圖表單傳遞過來的資料的。當時那也是Mvc預設幫我們實現了的模型板頂。現在我們就開始說人工實現模型繫結)

那這個繫結具體是繫結什麼呢?其實就是將從Index檢視中的表單元素繫結到我們自定義的Person類物件中。我們使用它的時候只要將引數上打一個[ModelBinder(typeof(PersonBinder))] 特性就行了。(其實我們可以在類,方法,屬性上面打上一個特性,同時我們也是可以在引數上面打上特性的)

例如:public ActionResult PostData([ModelBinder(typeof(PersonBinder))] Person per)  這就是給引數per打上了一個[ModelBinder(typeof(PersonBinder))]特性標籤

----------------------------》好了我們進入正題

實現模型繫結需要實現IModelBinder介面

下面我們來建立一個PersonBinder.cs類。然後讓這個類繼承IModelBinder介面。在這個類中我們來實現模型繫結

namespace MvcApp.Common
{
    public class PersonBinder:IModelBinder
    {
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var request = controllerContext.HttpContext.Request; //獲取請求的上下文

            Person p = new Person();

            //--------這裡的意思其實就是將從檢視傳遞過來的表單資料繫結到 Person類的一個p物件上

            p.Id = int.Parse(request["w_id"]);    //將前臺頁面傳遞過來的 id="w_id" 的表單元素的值繫結到Person類物件的Id屬性上
            p.Name = request["w_name"];            //將前臺頁面傳遞過來的 id="w_name" 的表單元素的值繫結到Person類物件的Name屬性上
            p.Age = int.Parse(request["w_age"]);   //將前臺頁面傳遞過來的 id="w_age" 的表單元素的值繫結到Person類物件的Age屬性上
            return p;            
        }
    }
}

以上就實現了將視圖表單繫結到Person類物件中了

那現在我們就在HomeController中類使用它

namespace MvcApp.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        //給引數per 前面打一個[ModelBinder(typeof(PersonBinder))]特性標籤。那麼當點選檢視的提交按鈕的時候,將表單元資料提交到PostData()方法前,會先執行PersonBinder.cs類中的BindModel方法。在這個BindModel方法中就將檢視中的表單資料的值賦值給Person了(即:將表單元素繫結到了Person物件上) 然後再進入PostData()方法,此時PostData([ModelBinder(typeof(PersonBinder))] Person per)方法中的per物件已經有值了。
        public ActionResult PostData([ModelBinder(typeof(PersonBinder))] Person per) //此時per裡的屬性已經綁定了各個表單元素的值了。
        {

            ViewBag.per = per;
            return View();
        }
    }
}