這篇文章主要介紹了ASP.NET全棧開發(fā)之在MVC中使用服務端驗證的示例,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
創(chuàng)新互聯(lián)服務項目包括陽新網(wǎng)站建設、陽新網(wǎng)站制作、陽新網(wǎng)頁制作以及陽新網(wǎng)絡營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關系等,向廣大中小型企業(yè)、政府機構等提供互聯(lián)網(wǎng)行業(yè)的解決方案,陽新網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務的客戶以成都為中心已經(jīng)輻射到陽新省份的部分城市,未來相信會繼續(xù)擴大服務區(qū)域并繼續(xù)獲得客戶的支持與信任!
在Action里調(diào)用驗證器來進行驗證,像這樣。
[HttpPost] public ActionResult ValidatorTest(Person model) {var result = this.ValidatorHub.PersonValidator.Validate(model); if (result.IsValid) { return Redirect("https://www.baidu.com"); }else { this.ValidatorErrorHandler(result); } return View(); }
很可惡,如果我需要驗證,我需要在每一個Action 里像這樣寫,一次實驗也就罷了,如果真要在每個Action里像這樣干,我想到時候你一定會很討厭這些代碼的。至少我是這樣認為。所以我很討厭我之前的寫法。
現(xiàn)在我想干嘛呢?我們知道其實MVC內(nèi)置了一個數(shù)據(jù)校驗。這里不過多介紹它,(偶爾適當?shù)恼照蛰喿樱灿性S多好處的)。這里簡單描述下它的用法。
[HttpPost] public ActionResult ValidatorTest(Person model) { if (ModelState.IsValid) { /// ok } return View(); }
和咱們之前那樣寫比起來是精簡了許多,但我還是覺得吧,他還是要在每個Action 里調(diào)用ModelState.IsValid,雖然只有一個if,但這不是我想要的,我希望它能像這樣
[HttpPost] public ActionResult ValidatorTest(Person model) { // // 一大堆代碼 // return Redirect("https://www.baidu.com"); }
不要影響我正常的編程,而我也不去做哪些重復的事。
換句話說,其實就是在執(zhí)行我Action之前就去把數(shù)據(jù)給校驗了。
于是我們想到了MVC給我們提供的Filter,OnActionExecuting,打開我們的ControllerEx,在里面重寫OnActionExecuting,他有一個參數(shù)ActionExecutingContext,通過名字我們大致了解了,這個參數(shù)是個Action相關的上下文,那他一定裝了Action相關的數(shù)據(jù)
我就不墨跡了,先直接上代碼,其實這些代碼也只是我剛剛才寫出來的而已,我對這個參數(shù)也不是很了解,通過一個一個去嘗試,慢慢得就試出來了。
protected override void OnActionExecuting(ActionExecutingContext filterContext) { var existError = false; foreach (var value in filterContext.ActionParameters.Values) { var modelValidatorPropertyInfo = this.ValidatorHub.GetType().GetProperty(value.GetType().Name + "Validator"); if (modelValidatorPropertyInfo != null) { var modelValidator = modelValidatorPropertyInfo.GetValue(this.ValidatorHub) as IValidator; var validateResult = modelValidator.Validate(value); if (!validateResult.IsValid) { this.ValidatorErrorHandler(validateResult); existError = true; } } } if (existError) { ViewData["Error"] = DicError; filterContext.Result = View(); } base.OnActionExecuting(filterContext); }
在 OnActionExecuting 里,我們首先定義了一個existError,用來判斷是否驗證失敗的,然后我們遍歷了 filterContext.ActionParameters.Values
在filterContext 里,我們看到ActionParameters 是關于Action的參數(shù)的,通過調(diào)試我發(fā)現(xiàn),他是一個集合,其鍵是參數(shù)名,比如拿我們這個Person來講。
[HttpPost] public ActionResult ValidatorTest(Person model) { // // 一大堆代碼 // return Redirect("https://www.baidu.com"); }
filterContext.ActionParameters 集合里就有一個數(shù)據(jù),其鍵是"model" 值呢 model
所以呢我們通過遍歷filterContext.ActionParameters.Value 就能取出每一個Action的所有參數(shù)了,而每一個參數(shù)通過.getType().Name 則能取出他的類型名,比如這里model類型是Person 所以filterContext.ActionParameters["model"].GetType().Name 就是“Person”了。
知道了實體是什么類型,如何獲取具體驗證器呢?想想我們的驗證器配置 Person = PersonValidator 那太簡單了,這不是一對一的關系嘛,但總不可能通過一個switch 去工廠返回吧,那這樣還需要維護一個工廠方法。當然不是咯,這就要用到咱.NET 提供的強大反射技術
有時候我們有一個匿名對象,是一個object的時候,又不知道它具體是什么類型,如何取它的屬性呢?
我這有一個方法,他能解決這個問題。
public static class ReflectHelper { public static object GetPropertyByAnonymousObject(string propertyName, object obj) { var property = obj.GetType().GetProperties().Where(p => p.Name == propertyName).FirstOrDefault(); if (property == null) { throw new Exception(string.Format("{0}對象未定義{1}屬性", nameof(obj), nameof(propertyName))); } return property.GetValue(obj); } }
從使用上,傳遞一個屬性名和對象進來,返回一個object的屬性。
我們看看內(nèi)部都做了些什么。
首先獲取類型,然后獲取執(zhí)行的屬性,誒,這個屬性可不是真的屬性哦,這個是PropertyInfo類型,是反射里的數(shù)據(jù)類型,它不是真正的屬性值,但我們?nèi)绻胍@取真正的屬性值怎么辦呢?其實只需要調(diào)用他的GetValue就行了,他有一個參數(shù),這個參數(shù)是指獲取那個對象上的屬性,于是把object傳進去就行。
有了這個基礎,反觀我們的目的,知道了Person,有一個對象叫ValidatotHub 里面有個屬性PersonValidator ,所以我們只需要獲取一個叫ValidatorHub對象里的PersonValidator屬性就行了。(Person是可替換的,是根據(jù)參數(shù)類型來的,前面已經(jīng)解釋過了,這里以Person舉例)
現(xiàn)在有個問題了,我們?nèi)〉降腜ersonValidator 是一個object類型的,object類型我可不好使用啊,我們又不能顯示的轉(zhuǎn)換為具體類型,因為誰知道具體類型是啥呢。如果寫死了就涼了。那肯定也不能用個switch來維護啊,那樣不又增加工作量了嗎。
我們慢慢發(fā)現(xiàn)PersonValidator繼承自AbstractValidator 現(xiàn)在我就可以在這里進行驗證了,我們知道value 就是那個model 所以直接對他進行驗證,驗證會返回一個ValidationResult類型接下來的事我就不解釋了,相信上一章已經(jīng)講得很清楚了。最后根據(jù)是否存在錯誤在進行提前處理,如果有錯誤的話就直接返回視圖呈現(xiàn)錯誤了,連咱們的Action都不執(zhí)行了。好了,到這里咱們昨天講得OnActionExecuted 可以直接Delete拉 。 我們現(xiàn)在把ValidatorTest里的驗證代碼都去掉來測試一下。 在 ValidatorTest 里打上斷點,然后什么都不填,直接提交。 斷點沒觸發(fā),但錯誤消息已呈現(xiàn)。多試幾次~. 同樣沒觸發(fā)。 那我們來一次正確的驗證。 斷點觸發(fā)了。并且值都通過了校驗 F5放行,最終我們的頁面跳轉(zhuǎn)到了 www.baidu.com。 感謝你能夠認真閱讀完這篇文章,希望小編分享的“ASP.NET全棧開發(fā)之在MVC中使用服務端驗證的示例”這篇文章對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián),關注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關知識等著你來學習! [HttpPost]
public ActionResult ValidatorTest(Person model)
{
//
// 一大堆代碼
//
return Redirect("https://www.baidu.com");
}
本文題目:ASP.NET全棧開發(fā)之在MVC中使用服務端驗證的示例
網(wǎng)頁URL:http://weahome.cn/article/geecos.html