<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        ASP.NET全棧開發教程之在MVC中使用服務端驗證的方法

        來源:懂視網 責編:小采 時間:2020-11-27 22:34:57
        文檔

        ASP.NET全棧開發教程之在MVC中使用服務端驗證的方法

        ASP.NET全棧開發教程之在MVC中使用服務端驗證的方法:前言 上一章我們在控制臺中基本的了解了FluentValidation是如何簡潔,優雅的完成了對實體的驗證工作,今天我們將在實戰項目中去應用它。 首先我們創建一個ASP.NET MVC項目,本人環境是VS2017, 創建成功后通過在Nuget中使用 Install-Packag
        推薦度:
        導讀ASP.NET全棧開發教程之在MVC中使用服務端驗證的方法:前言 上一章我們在控制臺中基本的了解了FluentValidation是如何簡潔,優雅的完成了對實體的驗證工作,今天我們將在實戰項目中去應用它。 首先我們創建一個ASP.NET MVC項目,本人環境是VS2017, 創建成功后通過在Nuget中使用 Install-Packag

        前言

        上一章我們在控制臺中基本的了解了FluentValidation是如何簡潔,優雅的完成了對實體的驗證工作,今天我們將在實戰項目中去應用它。

        首先我們創建一個ASP.NET MVC項目,本人環境是VS2017,

        創建成功后通過在Nuget中使用 Install-Package FluentValidation -Version 7.6.104 安裝FluentValidation

        在Model文件夾中添加兩個實體Address 和 Person

        public class Address
         {
         public string Home { get; set; }
        
         public string Phone { get; set; }
         }
        public class Person
         {
         /// <summary>
         /// 姓名
         /// </summary>
         public string Name { get; set; }
         /// <summary>
         /// 年齡
         /// </summary>
         public int Age { get; set; }
         /// <summary>
         /// 性別
         /// </summary>
         public bool Sex { get; set; }
        
         /// <summary>
         /// 地址
         /// </summary>
         public Address Address { get; set; }
         }

        緊接著創建實體的驗證器

        public class AddressValidator : AbstractValidator<Address>
         {
         public AddressValidator()
         {
         this.RuleFor(m => m.Home)
         .NotEmpty()
         .WithMessage("家庭住址不能為空");
        
         this.RuleFor(m => m.Phone)
         .NotEmpty()
         .WithMessage("手機號碼不能為空");
         }
         }
        public class PersonValidator : AbstractValidator<Person>
         {
         public PersonValidator()
         {
         this.RuleFor(p => p.Name)
         .NotEmpty()
         .WithMessage("姓名不能為空");
        
         this.RuleFor(p => p.Age)
         .NotEmpty()
         .WithMessage("年齡不能為空");
        
         this.RuleFor(p => p.Address)
         .SetValidator(new AddressValidator());
        
         }
         }

        為了更好的管理驗證器,我建議將使用一個Manager者來管理所有驗證器的實例。如ValidatorHub

        public class ValidatorHub
         {
         public AddressValidator AddressValidator { get; set; } = new AddressValidator();
        
         public PersonValidator PersonValidator { get; set; } = new PersonValidator();
         }

        現在我們需要創建一個頁面,在默認的HomeController 控制器下添加2個Action:ValidatorTest,他們一個用于展示頁面,另一個則用于提交。

        [HttpGet]
         public ActionResult ValidatorTest()
         {
         return View();
         }
        
         [HttpPost]
         public ActionResult ValidatorTest(Person model)
         {
         return View();
         }

        為 ValidatorTest 添加視圖,選擇Create模板,實體為Person

        將默認的@Html全部刪掉,因為在我們本次介紹中不需要,我們的目標是搭建一個前后端分離的項目,而不要過多的依賴于MVC。

        最終我們將表單改寫成了

        @using (Html.BeginForm())
        {
         @Html.AntiForgeryToken()
        
         <div class="form-horizontal">
         <h4>Person</h4>
         <hr />
         @Html.ValidationSummary(true, "", new { @class = "text-danger" })
         <div class="form-group">
         <label for="Name" class="control-label col-md-2">姓名</label>
         <div class="col-md-10">
         <input type="text" name="Name" class="form-control" />
         </div>
         </div>
        
         <div class="form-group">
         <label for="Age" class="control-label col-md-2">年齡</label>
         <div class="col-md-10">
         <input type="text" name="Age" class="form-control" />
         </div>
         </div>
        
         <div class="form-group">
         <label for="Home" class="control-label col-md-2">住址</label>
         <div class="col-md-10">
         <input type="text" name="Address.Home" class="form-control" />
         </div>
         </div>
        
         <div class="form-group">
         <label for="Phone" class="control-label col-md-2">電話</label>
         <div class="col-md-10">
         <input type="text" name="Address.Phone" class="form-control" />
         </div>
         </div>
        
         <div class="form-group">
         <label for="Sex" class="control-label col-md-2">性別</label>
         <div class="col-md-10">
         <div class="checkbox">
         <input type="checkbox" name="Sex" />
         </div>
         </div>
         </div>
        
         <div class="form-group">
         <div class="col-md-offset-2 col-md-10">
         <input type="submit" value="Create" class="btn btn-default" />
         </div>
         </div>
         </div>
        }

        注意,由于我們的實體Person中存在復雜類型Address,我們都知道,表單提交默認是Key:Value形式,而在傳統表單的key:value中,我們無法實現讓key為Address的情況下Value為一個復雜對象,因為input一次只能承載一個值,且必須是字符串。實際上MVC中存在模型綁定,此處不作過多介紹(因為我也忘記了-_-||)。

        簡單的說就是他能根據你所需要類型幫我們自動盡可能的轉換,我們目前只要知道如何正確使用,在Address中存在Home屬性和Phone屬性,我們可以將表單的name設置為Address.Home,MVC的模型綁定會將Address.Home解析到對象Address上的Home屬性去。

        簡單的校驗方式我也不過多介紹了。再上一章我們已經了解到通過創建一個實體的驗證器來對實體進行驗證,然后通過IsValid屬性判斷是否驗證成功。對,沒錯,對于大家來說這太簡單了。但我們每次校驗都創建一個驗證器是否顯得有點麻煩呢?不要忘了我們剛剛創建了一個ValidatorHub,我們知道控制器默認繼承自Controller,如果我們想為控制器擴展一些能力呢?現在我要創建一個ControllerEx了,并繼承自Controller。

        public class ControllerEx : Controller
         {
         protected Dictionary<string, string> DicError { get; set; } = new Dictionary<string, string>();
        
         protected ValidatorHub ValidatorHub { get; set; } = new ValidatorHub();
        
         protected override void OnActionExecuted(ActionExecutedContext filterContext)
         {
         base.OnActionExecuted(filterContext);
         ViewData["Error"] = DicError;
         }
        
         protected void ValidatorErrorHandler(ValidationResult result)
         {
         foreach (var failure in result.Errors)
         {
         if (!this.DicError.ContainsKey(failure.PropertyName))
         {
         this.DicError.Add(failure.PropertyName, failure.ErrorMessage);
         }
         }
         }
         }

        在ControllerEx里我創建了一個ValidatorHub屬性,正如其名,他內部存放著各種驗證器實體呢。有了它,我們可以在需要驗證的Action中通過this.ValidatorHub.具體驗證器就能完成具體驗證工作了,而不需要再去每次new 一個驗證器。

        同樣我定義了一個DicError的鍵值對集合,他的鍵和值類型都是string。key是驗證失敗的屬性名,而value則是驗證失敗后的錯誤消息,它是用來存在驗證的結果的。

        在這里我還定義了一個ValidatorErrorHandler的方法,他有一個參數是驗證結果,通過名稱我們大致已經猜到功能了,驗證錯誤的處理,對驗證結果的錯誤信息進行遍歷,并將錯誤信息添加至DicError集合。

        最終我需要將這個DicError傳遞給View,簡單的辦法是ViewData["Error"] 但我不想在每個頁面都去這么干,因為這使我要重復多次寫這行代碼,我會厭倦它的。很棒的是MVC框架為我們提供了Filter(有的地方也稱函數鉤子,切面編程,過濾器),能夠方便我們在生命周期的不同階段進行控制,很顯然,我的需求是在每次執行完Action后要在末尾添加一句ViewData["Error"]=DicError。于是我重寫了OnActionExecuted方法,僅添加了 ViewData["Error"] = DicError;

        現在我只需要將HomeController繼承自ControllerEx即可享受以上所有功能了。

        現在基本工作基本都完成了,但我們還忽略了一個問題,我錯誤是存在了ViewData["Error"]里傳遞給View,只不過難道我們在驗證錯誤的時候在頁面顯示一個錯誤列表?像li一樣?這顯然不是我們想要的。我們還需要一個幫助我們合理的顯示錯誤信息的函數。在Razor里我們可以對HtmlHelper進行擴展。于是我為HtmlHelper擴展了一個方法ValidatorMessageFor

        public static class ValidatorHelper
         {
         public static MvcHtmlString ValidatorMessageFor(this HtmlHelper htmlHelper, string property, object error)
         {
         var dicError = error as Dictionary<string, string>;
        
         if (dicError == null) //沒有錯誤
         {
         // 不會等于空
         }
         else
         {
         if (dicError.ContainsKey(property))
         {
         return new MvcHtmlString(string.Format("<p>{0}</p>", dicError[property]));
         }
         }
         return new MvcHtmlString("");
         }
         }

        在ValidatorMessaegFor里需要2個參數property 和 error

        前者是需要顯示的錯誤屬性名,后者則是錯誤對象即ViewData["Error"],功能很簡單,在發現錯誤對象里存在key為錯誤屬性名的時候將value用一個p標簽包裹起來返回,value即為錯誤屬性所對應的錯誤提示消息。

        現在我們還需要在View每一個input下添加一句如: @Html.ValidatorMessageFor("Name", ViewData["Error"])即可。

        @using (Html.BeginForm())
        {
         @Html.AntiForgeryToken()
        
         <div class="form-horizontal">
         <h4>Person</h4>
         <hr />
         @Html.ValidationSummary(true, "", new { @class = "text-danger" })
         <div class="form-group">
         <label for="Name" class="control-label col-md-2">姓名</label>
         <div class="col-md-10">
         <input type="text" name="Name" class="form-control" />
         @Html.ValidatorMessageFor("Name", ViewData["Error"])
         </div>
         </div>
        
         <div class="form-group">
         <label for="Age" class="control-label col-md-2">年齡</label>
         <div class="col-md-10">
         <input type="text" name="Age" class="form-control" />
         @Html.ValidatorMessageFor("Name", ViewData["Error"])
         </div>
         </div>
        
         <div class="form-group">
         <label for="Home" class="control-label col-md-2">住址</label>
         <div class="col-md-10">
         <input type="text" name="Address.Home" class="form-control" />
         @Html.ValidatorMessageFor("Address.Home", ViewData["Error"])
         </div>
         </div>
        
         <div class="form-group">
         <label for="Phone" class="control-label col-md-2">電話</label>
         <div class="col-md-10">
         <input type="text" name="Address.Phone" class="form-control" />
         @Html.ValidatorMessageFor("Address.Phone", ViewData["Error"])
         </div>
         </div>
        
         <div class="form-group">
         <label for="Sex" class="control-label col-md-2">性別</label>
         <div class="col-md-10">
         <div class="checkbox">
         <input type="checkbox" name="Sex" />
         </div>
         </div>
         </div>
        
         <div class="form-group">
         <div class="col-md-offset-2 col-md-10">
         <input type="submit" value="Create" class="btn btn-default" />
         </div>
         </div>
         </div>
        }

        到此我們的所有基本工作都已完成

        [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();
         }

        通過我們在ControllerEx種的ValidatorHub來對實體Person進行校驗,如果校驗成功了....這里沒啥可干的就當跳轉一下表示咯,否則的話調用Ex中的ValidatorErrorHandler 將錯誤消息綁定到ViewData["Error"]中去,這樣就能在前端View渲染的時候將錯誤消息顯示出來了。

        接下來我們將程序跑起來。

        正如大家所看到的,當我點擊提交的時候 雖然只有電話沒輸入但其他三個表單被清空了,也許我們會覺得不爽,當然如果你需要那相信你在看完上述的錯誤信息綁定后一定也能解決這個問題的,但事實上,我們并不需要它,\(^o^)/~

        為什么呢?因為我們還要前端驗證啊,當前端驗證沒通過的時候根本無法發送到后端來,所以不用擔心用戶在一部分驗證失敗時已填寫的表單數據被清空掉。

        這里提到在表單提交時需要前端校驗,既然有前端校驗了為何還要我們做后臺校驗呢?不是脫了褲子放屁嗎?事實上,前端校驗的作用在于優化用戶體驗,減輕服務器壓力,也可以防住君子,但絕不能防止小人,由于Web客戶端的不確定性,任何東西都可以模擬的。如果不做服務端驗證,假如你的系統涉及金錢,也許那天你醒來就發現自己破產了。

        來一個通過驗證的。

        總結

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        ASP.NET全棧開發教程之在MVC中使用服務端驗證的方法

        ASP.NET全棧開發教程之在MVC中使用服務端驗證的方法:前言 上一章我們在控制臺中基本的了解了FluentValidation是如何簡潔,優雅的完成了對實體的驗證工作,今天我們將在實戰項目中去應用它。 首先我們創建一個ASP.NET MVC項目,本人環境是VS2017, 創建成功后通過在Nuget中使用 Install-Packag
        推薦度:
        標簽: 驗證 驗證的 mvc
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 精品亚洲综合在线第一区| 国产精品无码一二区免费 | 午夜免费不卡毛片完整版| 亚洲另类自拍丝袜第1页| 久久免费的精品国产V∧| 亚洲视频在线免费观看| 久久久精品2019免费观看| 91久久亚洲国产成人精品性色| 91精品手机国产免费| 亚洲视屏在线观看| 亚洲w码欧洲s码免费| 国产午夜亚洲精品| 成年人免费观看视频网站| 无码日韩精品一区二区免费| 亚洲国产高清美女在线观看| 国产男女爽爽爽爽爽免费视频| 亚洲一级免费毛片| 日韩高清免费在线观看| 日韩亚洲人成在线综合| 国产亚洲精品激情都市| 九九美女网站免费| 亚洲国产成人综合| 永久免费bbbbbb视频| 一区二区视频在线免费观看| 亚洲成AV人片在| 欧美a级成人网站免费| 亚洲精品av无码喷奶水糖心| 成人免费黄色网址| 亚洲91精品麻豆国产系列在线| 日韩精品视频免费观看| a高清免费毛片久久| 亚洲国产一区国产亚洲 | 免费国产在线观看老王影院| 一级美国片免费看| 亚洲天天在线日亚洲洲精| 天天看免费高清影视| 狠狠躁狠狠爱免费视频无码| 亚洲一区二区三区亚瑟| 亚洲第一区在线观看| 91在线老王精品免费播放| 色噜噜噜噜亚洲第一|