<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Asp.net MVC 示例項目"Suteki.Shop"分析之---數據驗證

           在Suteki.Shop,實現了自己的數據校驗機制,可以說其設計思路還是很有借鑒價值的。而使用
      這種機制也很容易在Model中對相應的實體對象(屬性)添加校驗操作方法。下面就來介紹一下其實
      現方式。

           首先,看一下這樣類圖:

           在Suteki.Shop定義一個“IValidatingBinder”接口,其派生自IModelBinder:  

      public interface IValidatingBinder : IModelBinder 
      {
          
      void UpdateFrom(object target, NameValueCollection values);
          
      void UpdateFrom(object target, NameValueCollection values, string objectPrefix);
          
      void UpdateFrom(object target, NameValueCollection values, ModelStateDictionary modelStateDictionary);
          
      void UpdateFrom(object target, NameValueCollection values, ModelStateDictionary modelStateDictionary, string objectPrefix);
      }

       

           其接口中定義了一個重載方法UpdateFrom,其要實現的功能與MVC中UpdateFrom一樣,就是自動讀取
      我們在form中定義的有些元素及其中所包含的內容。  

           實現IValidatingBinder接口的類叫做:ValidatingBinder,下面是其核心代碼說明。
         
           首先是BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
      該方法是在IModelBinder接口中定義的,是其核心功能,用于將客戶端數據轉成我們希望Model類型。
             

      /// <summary>
      /// IModelBinder.BindModel
      /// </summary>
      /// <param name="controllerContext"></param>
      /// <param name="bindingContext"></param>
      /// <returns></returns>
      public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
      {
          
      if (bindingContext == null)
          {
              
      throw new ArgumentNullException("bindingContext");
          }

          
      if (IsBasicType(bindingContext.ModelType))
          {
              
      return new DefaultModelBinder().BindModel(controllerContext, bindingContext);
          }

          var instance 
      = Activator.CreateInstance(bindingContext.ModelType);
          var request 
      = controllerContext.HttpContext.Request;

          var form 
      = request.RequestType == "POST" ? request.Form : request.QueryString;

          UpdateFrom(instance, form);

          
      return instance;
      }

         

            上面代碼第二個if 用于判斷bindingContext的Model類型是否是系統類型,比如decimal,string等。
      如果是則使用MVC自帶的DefaultModelBinder來進行處理。否則就使用該類自己的UpdateFrom方法,從而
      實現對當前form中的數據與Model中相應類型的信息綁定,并返相應的 Model 實例(instance)。下面
      是其核心代碼:

       

      public virtual void UpdateFrom(BindingContext bindingContext)
      {
          
      foreach (var property in bindingContext.Target.GetType().GetProperties())
          {
              
      try
              {
                  
      foreach (var binder in propertyBinders)
                  {
                      binder.Bind(property, bindingContext);
                  }
              }
              
      catch (Exception exception)
              {
                  
      if (exception.InnerException is FormatException ||
                      exception.InnerException 
      is IndexOutOfRangeException)
                  {
          
      string key = BuildKeyForModelState(property, bindingContext.ObjectPrefix);
                      bindingContext.AddModelError(key, bindingContext.AttemptedValue, 
      "Invalid value for {0}".With(property.Name));
          bindingContext.ModelStateDictionary.SetModelValue(key, 
      new ValueProviderResult(bindingContext.AttemptedValue, bindingContext.AttemptedValue, CultureInfo.CurrentCulture));
                  }
                  
      else if (exception is ValidationException)
                  {
          
      string key = BuildKeyForModelState(property, bindingContext.ObjectPrefix);
                      bindingContext.AddModelError(key, bindingContext.AttemptedValue, exception.Message);
          bindingContext.ModelStateDictionary.SetModelValue(key, 
      new ValueProviderResult(bindingContext.AttemptedValue, bindingContext.AttemptedValue, CultureInfo.CurrentCulture));
                  }
                  
      else if (exception.InnerException is ValidationException)
                  {
          
      string key = BuildKeyForModelState(property, bindingContext.ObjectPrefix);
                      bindingContext.AddModelError(key, bindingContext.AttemptedValue, exception.InnerException.Message);
          bindingContext.ModelStateDictionary.SetModelValue(key, 
      new ValueProviderResult(bindingContext.AttemptedValue, bindingContext.AttemptedValue, CultureInfo.CurrentCulture));
                  }
                  
      else
                  {
                      
      throw;
                  }
              }

          }
          
      if (!bindingContext.ModelStateDictionary.IsValid)
          {
              
      throw new ValidationException("Bind Failed. See ModelStateDictionary for errors");
          }
      }


           上面代碼中的TRY部分就是其數據綁定的代碼,而其Catch部分實現了在數據綁定過程中出現的
      錯誤異常(主要是數據驗證等,會在后面提到)收集到ModelState(ModelStateDictionary)中
      便于后續處理。而這里Suteki.Shop還定義了自己的驗證異常類“ValidationException”(位于:
      Suteki.Common\Validation\ValidationException.cs,因為代碼很簡單,就不多做解釋了。

          有了ValidatingBinder之后,下面就來看一下Suteki.Shop是如何使用它的。這里以一個業務
      流程---“編輯用戶”來進行說明。
       
          下面就是UserController(Suteki.Shop\Controllers\UserController.cs) 中的Edit操作:

      [AcceptVerbs(HttpVerbs.Post), UnitOfWork]
      public ActionResult Edit([DataBind] User user, string password)
      {
       
      if(! string.IsNullOrEmpty(password))
       {
        user.Password 
      = userService.HashPassword(password);
       }
          ..    
      }


           在該Action中,我們看到其定義并使用了DataBind這個ModelBinder進行綁定處理,所以我們要
      先看一下DataBinder(注:它是Suteki.Shop中關于數據綁定的“ModelBinder的基類)中倒底做了
      些什么,下面是其實現代碼:
         

      public class DataBinder : IModelBinder, IAcceptsAttribute
      {
      public virtual object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
       {
        
      object entity;

        
      if(declaringAttribute == null || declaringAttribute.Fetch)
        {
         entity 
      = FetchEntity(bindingContext, controllerContext);
        }
        
      else 
        {
         entity 
      = Activator.CreateInstance(bindingContext.ModelType);
        }
        
        
      try
        {
         validatingBinder.UpdateFrom(entity, controllerContext.HttpContext.Request.Form, bindingContext.ModelState, bindingContext.ModelName);
        }
        
      catch(ValidationException ex) 
        {}

        
      return entity;
       } 
       
      }

       

            其BindModel方法中“獲取當前要編輯的用戶數據操作”就是通過下面這一行完成的:      

      FetchEntity(bindingContext, controllerContext)


            
           而try中的代碼validatingBinder.UpdateFrom()就是對上面所說的“ValidatingBinder”中的
      “UpdateFrom”調用。通過UpdateFrom之后就會將綁定時出現的錯誤異常進行收集。

           有了這種綁定,可以說設置上完成了,而如何將驗證規則綁定到相應的Model對象上呢?
         
           為了實現這個功能,Suteki.Shop提供了一個叫做ValidationProperty的泛型類,它提供了對于
      數字,是否為空, IsDecimal,最大值,最小值,IsEmail等驗證功能。并以擴展方法的行式提供出
      來,相應代碼如下:     

      Code

          
           使用它就可以很方便的對Model中的相關屬性添加驗證規則了。以User為例,其驗證規則添加
      內容如下(Suteki.Shop\Models\User.cs):

      public void Validate()
      {
         Validator validator 
      = new Validator
         {
             () 
      => Email.Label("Email").IsRequired().IsEmail(),
             () 
      => Password.Label("Password").IsRequired(),
         };

          validator.Validate();
      }

          
          在規則添加完成后,就把對獲取到的信息進行驗證了,下面是驗證的實現方法:

      public class Validator : List<Action>
      {
          
      public void Validate()
          {
              var errors 
      = new List<ValidationException>();

              
      foreach (Action validation in this)
              {
                  
      try
                  {
                      validation();
                  }
                  
      catch (ValidationException validationException)
                  {
                       errors.Add(validationException);
                  }
              }

              
      if (errors.Count > 0)
              {
                  
      //backwards compatibility
                  string error = string.Join("", errors.Select(x => x.Message + "<br />").ToArray());
                  
      throw new ValidationException(error, errors);
              }
          }
      }

       

            代碼比較簡單,大家看一下就可以了。
         
            到這里,主要的代碼就介紹完了,下面再后到UserController中看看Action是如何調用驗證方法
      并發驗證錯誤信息復制到ModelState中的,接著看一下編輯用戶信息這個Action:

      [AcceptVerbs(HttpVerbs.Post), UnitOfWork]
      public ActionResult Edit([DataBind] User user, string password)
      {
          
      if(! string.IsNullOrEmpty(password))
          {
             user.Password 
      = userService.HashPassword(password);
          }

          
      try
          {
              user.Validate();
          }
          
      catch (ValidationException validationException)
          {
              validationException.CopyToModelState(ModelState, 
      "user");
              
      return View("Edit", EditViewData.WithUser(user));
          }

          
      return View("Edit", EditViewData.WithUser(user).WithMessage("Changes have been saved")); 
      }

           

            大家看到了吧,Try中的user.Validate()就是啟動驗證的功能,而在Catch中使用CopyToModelState
      方法將錯誤信息Copy到當前Controller中的ModelState中,如下:

      public void CopyToModelState(ModelStateDictionary dictionary, string prefix)
      {
          
      foreach(var error in errors)
          {
              
      string key = string.IsNullOrEmpty(prefix) ? error.propertyKey : prefix + "." + error.propertyKey;

             dictionary.AddModelError(key, error.Message);
          }

       

           這樣在前臺View中,通過Html.ValidationSummary()方法來顯示驗證結果,現在我們看一下最終的
      運行效果:

          以“輸入錯誤的Email地址”為例:
          
         
          
          好了,今天的內容就先到這里了。
         
          原文鏈接:http://www.rzrgm.cn/daizhj/archive/2009/05/18/1452735.html

          作者: daizhj,代震軍,LaoD

          Tags: mvc,Suteki.Shop

          網址: http://daizhj.cnblogs.com/   

         

      posted @ 2009-05-18 09:18  代震軍  閱讀(7111)  評論(12)    收藏  舉報
      主站蜘蛛池模板: 四川丰满少妇无套内谢| 妖精视频yjsp毛片永久| 日本丰满少妇裸体自慰| 国产在线啪| 四虎影视4hu4虎成人| 久久一日本道色综合久久| 国产无套内射又大又猛又粗又爽 | 日韩中文字幕综合第二页| 国产偷国产偷亚洲高清日韩| 国产成人精品无码免费看| 99福利一区二区视频| 国产精品一区二区在线蜜芽tv| 男女激情一区二区三区| ww污污污网站在线看com| 久久这里有精品国产电影网 | 欧美丰满熟妇bbbbbb| 亚洲人成亚洲人成在线观看| 亚洲精品美女一区二区| 久久夜色精品国产亚洲a| 精品国产色情一区二区三区| 一区二区中文字幕久久| 亚洲综合色婷婷中文字幕| 丁香婷婷色综合激情五月| 中文字幕精品无码一区二区三区| 无码人妻斩一区二区三区| 中文字幕人妻日韩精品| 337p日本欧洲亚洲大胆色噜噜| 军人粗大的内捧猛烈进出视频 | 亚洲精品一区二区天堂| 中年国产丰满熟女乱子正在播放| 少妇人妻偷人精品免费| 亚洲永久精品日韩成人av| 免费的特黄特色大片| 亚洲a人片在线观看网址| 自拍视频亚洲精品在线| 国产欧美在线观看一区| 国产超碰无码最新上传| 干老熟女干老穴干老女人| 丰满少妇呻吟高潮经历| 国产成人亚洲综合图区| 久久精品国产亚洲av久|