Asp.net MVC: BindingHelperExtension的UpdateFrom如何使用?

預備知識:擴展方法(Extension Method)Asp.net MVC

一般的做法

以修改一篇blog爲例,當我們再輸入框中輸入了修改的內容之後,通過點擊提交按鈕將新的blog內容提交到服務器端,如圖所示,我們可以修改blog的title,body和timestamp三項:

 image

圖 1

我們可能寫出這樣的代碼:

[ControllerAction]
public void Save(int id)
{  
    BlogDataContext dbBlog = new BlogDataContext();
    Post post = dbBlog.Posts.Single(p => p.ID == id);
    post.Body = Request.Form["Body"];
    post.Title = Request.Form["Title"];
    post.Timestamp = DateTime.Parse(Request.Form["Timestamp"]);

    dbBlog.SubmitChanges();
    RedirectToAction(new { action = "Detail", id = post.ID });   
}
 

這段代碼顯示了controller從view的Request中讀取內容,然後更新model。在新的Asp.net模型中,view的內容都放在Request.Form對象中,該對象是一個HttpValueCollection集合。

image

圖 2

仔細看它裏面存儲的值,實際上就是我們在以前看到的Request.QueryString,只是現在我們不用在Url中顯示地用?來寫出,而是由Asp.net MVC框架幫我們生成,它會自動讀取我們在form中定義的有些元素及其中所包含的內容。下面是一個form的例子,紅色標註的地方可以先忽略:

image

圖 3

BindingHelperExtension.UpdateFrom讓更新變得更加容易

回到更新blog內容的問題上來,下面的代碼可以完成更新任務:

post.Body = Request.Form["Body"]; 
post.Title = Request.Form["Title"]; 
post.Timestamp = DateTime.Parse(Request.Form["Timestamp"]);

但是這樣一個屬性一個屬性地修改Model的值很繁瑣,而且中間涉及到類型轉換。比如上面的DateTime類型的屬性Timestamp,嚴格的說我們應該在更新它的值之前坐類型判斷,空值判斷等等操作。當屬性超過10個甚至更多時,更新屬性的代碼加上類型轉換,錯誤處理等等,代碼的數量就比較打了。那麼有沒有更加簡便的做法呢?實際上在MvcToolkit.dll這個程序集中爲我們提供了一個簡化操作的類,它就是UrlHelper,是一個擴展方法,可以附加到任何的Object類型的對象上

image

圖 4

添加對MvcToolkit.dll的引用,並引入名字空間

using System.Web.Mvc.BindingHelpers;

之後我們就可以使用BindingHelpExtension類了。

[ControllerAction]
public void Save(int id)
{  
    BlogDataContext dbBlog = new BlogDataContext();
    Post post = dbBlog.Posts.Single(p => p.ID == id);
post.UpdateFrom(Request.Form); //post.Body = Request.Form["Body"]; //post.Title = Request.Form["Title"]; //post.Timestamp = DateTime.Parse(Request.Form["Timestamp"]); dbBlog.SubmitChanges(); RedirectToAction(new { action = "Detail", id = post.ID }); }

這樣修改一個對象的屬性是不是很簡單呢?毫無疑問,而且這樣還帶來了另外一個好處,如果這個時候Post的屬性變了(屬性名或屬性個數),我們不需要修改Controller的代碼,需要修改的只是View部分

使用UpdateFrom的前提

UpdateFrom固然很好用,可是需要配合Form的Action來完成,而且它對於view中元素的定義有一定的要求。

  • Url.Action

先來看看Action。我們爲Form添加Action,注意method屬性是post的,因爲是提交給服務器。

<form action="<%= Url.Action(new {action="Save",id=ViewData.ID}) %>method="post">

這裏action的語法有一點怪異,實際上它生成後的Url是這樣的:

<form action="/MVCStudy/Blog/Save/10"  method="post"> 

這裏的Url實際上ViewPage的一個屬性,而該屬性又是UrlHelper的一個實例,所以這裏的Url.Action實際上System.Web.Mvc.UrlHelper類的方法Action,該類存在於System.Web.Extension.dll程序集中。

image

圖 5

至於Url.Action方法生成Url的原理,可以參考Scott的文章“ASP.NET MVC Framework's Routing Engine

  • HtmlName——指定HtmlName,updatefrom才能生效。

這裏的HtmlName是指在使用HtmlHelper類來生成html元素時所需要指定的相應的html元素的名字:

image

圖 6

比如:

image

圖 7

這裏雖然生成id和name兩個屬性,但是Asp.net MVC使用的"name"。生成這一元素的代碼:

        <p class="body">
            <%--<%=Html.TextArea("bodyOfBlog",ViewData.Body) %>--%>
            <%=Html.TextArea("Body",ViewData.Body) %>            
        </p>

注意這裏HtmlName一定要與對應的model的屬性名一致,否則無法完成更新。上述代碼中註釋掉的代碼行就是這樣一個例子。正確的HtmlName設定,請參考本文圖3。

總結

使用UpdateFrom可以爲我們帶來很多便利,例如類型轉換、空值檢查之類,同時它也使得代碼更加容易維護,因爲在controller中不需要理會model的具體的屬性,充分發揮了Data Banding的作用。讓框架爲我們做更多的事,那麼我們就可以更省事。

如果你的UpdateFrom不起作用,那麼首先應該檢查一下Form的action以及HtmlName的設定是否正確.


引用通告
此日誌的引用通告 URL 是:
http://raderdotnet.spaces.live.com/blog/cns!3461738A506327E!542.trak
引用此項的網絡日誌

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章