ASP.NET MVC數據驗證

作者: 桂素偉  來源: 博客園  發布時間: 2009-09-11 10:59  閱讀: 2969 次  推薦: 0   原文鏈接   [收藏]  
摘要:本文講解了ASP.NET MVC的數據驗證的一些知識

關于ASP.NET MVC的驗證,用起來很特別,因為MS的封裝,使人理解起來很費解。也可能很多人都在Scott Guthrie等人寫的一本《ASP.NET MVC 1.0》書中,見過NerdDinner項目中對Dinner對象修改和添加的時的數據驗證。但有許多封裝的地方,不知道是怎樣的工作原理,今天研究了,拿出來給大家分享一下。

數據庫還是上一篇blog中的庫與表,同樣的方法來創建news表的實體類,在自動生成的news這個實體類中,我們發現有一個特殊的分部方法:

partial void OnValidate(System.Data.Linq.ChangeAction action);

這個方法沒有實現,我們根據C#的語法知道,如果分部類中的分部方法,沒有實現的話,調用和定議的地方都不會起什么作用。現在,我們要去完善這個方法,讓它“用”起來。

首先,人產在Models中創建news類的另一部分,代碼如下:

Code

 

在這里給出這么多代碼,其實是提前有設計的,因為從業務角度考慮,還不應該寫這部分代碼。RuleViolation類很簡單,就是一個包括了兩個屬性的類(這個類的結構設計是根據后面的ModelState.AddModelError主法來設計的)。

news分部類中,有一個IsValid的屬性,這個屬性是bool類型的,返回值取決于GetRuleViolations這個方法,這個方法返回值是一個IEnumerable類型的,IEnumerable是通過news的幾個屬性是否為空來生成跌代的。如果titlecontentsNull””,就返回跌代。其實真正的用戶數據的驗證就是在這里實現,用戶的數據的對與錯,就是一個邏輯,只要用戶數據不符合規則,就可以 “yield return new RuleViolation("錯誤標識","錯誤提示信息!");這里的錯誤碼提示信息是顯示到客戶端的,所以要處理好友好的提示。

現在驗證用戶數據,生成錯誤列表的工作都做完了,但關鍵是怎么能讓用戶提交數據時,調用OnValidate。這個問題,先放一下,請記住,上面的代碼,只要在用戶提交數據時,調用OnValidate,這樣就能得到錯誤集合。

現在,讓我們來處理CotrollerView層,在Cotroller層,首先來添加index這個Action,代碼如下:

1public ActionResult Index()
2        {           
3            var NewsList = DCDC.news.Select(newss=>newss);
4            return View(NewsList );
5     }
6

這個Action返回所有news表中的記錄。

對應的View如下:

Code

 

代碼中,需要我們注意是的   

因為要導航到EditView,把以接下來我們創建EditActionView(因為在編輯數據時,要用到驗證,Edit才是我們的重點)

1 public ActionResult Edit(int id)
2        {
3            var list = DCDC.news.Single(newss=>newss.ID ==id);
4            return View(list);
5     }
6

 

 

<%= Html.ActionLink("Edit", "Edit", new { id=item.ID }) %>

中的id會被當成參數送到EditControllerEdit(int id)Action,成為Edit方法的實參。

Edit.aspx頁面如下圖:

對應EditAction生成view,代碼如下:

Code

 

如果要單擊“更新”返回數據新數據,還需要我們寫如下一個Action

Code

 

這個Edit的Action是用戶提交返來更新數據庫的,我們可以從formValuews得到用戶在頁面上更新的數據,來更新Sig_news對象,然后調用DCDC.SubmitChanges();去更新數據庫,如果沒有民常,會導航到index.aspx頁面。如果發生異常,就會運行到catch里。如果還記得,在本文的前半部分,我們說到OnValidate,是數據在提交時應該驗證,但在這里,我們并沒有顯示的調用OnValidate這個方法,但實際運行中,我們發現,這個方法被執行了,如果我們建立跟蹤,把斷點設在DCDC.SubmitChanges();如果我們數據有民常,會發現當DCDC.SubmitChanges();執行完后就會跳到partial void OnValidate(System.Data.Linq.ChangeAction action)這個方法,這是怎么做到的呢?我們猜測,一定是在數據提交時,調用OnValidate這個方法。為了找到它們的關系,只好用Reflector.exe來“探測”一下了(Reflector.exe的用法就不說了)。

SubmitChanges方法是DataContext的一個方法,這個類位于System.Data.Linq命空間下,用Reflector.exe打開SubmitChanges,看到this.SubmitChanges(ConflictMode.FailOnFirstConflict);定位這個方法,可以看到new ChangeProcessor(this.services, this).SubmitChanges(failureMode);定位查找會發現ValidateAll(orderedList);在這個方法中,多處看到 SendOnValidate(obj2.Type, obj2, ChangeAction.Insert);這個方法,再定位,有這樣一行代碼 type.OnValidateMethod.Invoke(item.Current, new object[] { changeAction });這里,正是通過反射調用了OnValidate這個方法。這樣我們就找到了SubmitChanges執行時調用OnValidate的方法了(其不用調用OnValidate也可以驗證用戶數據,只需要寫個方法,在SubmitChanges 提交以前執行就可以達到同樣效果)。同時,當發生異常時,OnValidate會拋出一個Application的異常,這里會被public ActionResult Edit(int id,FormCollection formValuews)方法中的Catch捕獲到,就執行如下代碼:

Code

 

 

這行代碼的意思是把錯誤的信息,以鍵值的方式放入ModelState中,ModelState是一個ModelStateDictionary類型,這個類型實現了IDictionary, ICollection>, IEnumerable>, IEnumerable這些接口(這里要注意,ModelState是當前對象的一個屬性,并且它的AddModelError方法的第一個參數key有其獨特的作用)。處理完異常后,還是返回當前頁面。這時你會發現,在頁面的   發生了變化,把我們錯誤的地方去提示出來了,這里就是,為什么我們把錯誤信息放到ModelState中,而錯誤則顯示在了Html.ValidationSummary中了呢?并且發生錯誤的數據后會加上了一個紅色的“*”,這是怎么樣做到的呢?

再次利用Reflector.exe,查看Html.ValidationSummary方法和Html.ValidationMessage方法,會發現它們顯示的數據是從ModelState 中獲取的,如果ModelState 這個集合中沒有數據,Html.ValidationSummary和Html.ValidationMessage就返回空,如果發生異常,this.ModelState中有子項,就會通過Html.ValidationSummary和Html.ValidationMessage在頁面頁上顯示出來。因為Html.ValidationMessage在頁面上有多個,所以在this.ModelState.AddModelError(v.PropertyName,v.ErrorMessage);方法中的v.PropertyName就有了用處了,這個值要與中的第一個參數對應,這樣才能起到作用,顯示出第二個參數“*”。

 

 

這樣一來,就達到了ASP.NET MVC的數據驗證。由于ASPNET MVC 驗證捌的彎比較多,所以下來用個圖來說明一下。




源碼:/Files/axzxs2001/MvcCompany.rar

0
0
 
標簽:MVC
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()