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

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

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

      Util應(yīng)用框架基礎(chǔ)(四) - 驗(yàn)證

      本節(jié)介紹Util應(yīng)用框架如何進(jìn)行驗(yàn)證.

      概述

      驗(yàn)證是業(yè)務(wù)健壯性的基礎(chǔ).

      .Net 提供了一套稱為 DataAnnotations 數(shù)據(jù)注解的方法,可以對屬性進(jìn)行一些基本驗(yàn)證,比如必填項(xiàng)驗(yàn)證,長度驗(yàn)證等.

      Util應(yīng)用框架使用標(biāo)準(zhǔn)的數(shù)據(jù)注解作為基礎(chǔ)驗(yàn)證,并對自定義驗(yàn)證進(jìn)行擴(kuò)展.

      基礎(chǔ)用法

      引用Nuget包

      Nuget包名: Util.Validation.

      通常不需要手工引用它.

      數(shù)據(jù)注解

      數(shù)據(jù)注解是一種.Net 特性 Attribute,可以在屬性上應(yīng)用它們.

      常用數(shù)據(jù)注解

      下面列出一些常用數(shù)據(jù)注解,如果還不能滿足需求,可以創(chuàng)建自定義的數(shù)據(jù)注解.

      • RequiredAttribute 必填項(xiàng)驗(yàn)證

        [Required] 驗(yàn)證屬性不能是空值.

        范例:

          public class Test {
              [Required]
              public string Name { get; set; }
          }
        

        [Required] 支持一些參數(shù),可以設(shè)置驗(yàn)證失敗的提示消息.

          public class Test {
              [Required(ErrorMessage = "名稱不能為空")]
              public string Name { get; set; }
          }
        
      • StringLengthAttribute 字符串長度驗(yàn)證

        [StringLength] 可以對字符串長度進(jìn)行驗(yàn)證.

        下面的例子驗(yàn)證 Name 屬性的字符串最大長度為 5.

          public class Test {
              [StringLength(5)]
              public string Name { get; set; }
          }
        

        還可以同時(shí)設(shè)置最小長度.

        下面驗(yàn)證 Name 屬性字符串最小長度為1,最大長度為 5.

          public class Test {
              [StringLength(5,MinimumLength = 1)]
              public string Name { get; set; }
          }
        
      • MaxLengthAttribute 字符串最大長度驗(yàn)證

        [MaxLength] 也可以用來驗(yàn)證字符串最大長度.

        驗(yàn)證 Name 屬性的字符串最大長度為 5.

          public class Test {
              [MaxLength(5)]
              public string Name { get; set; }
          }
        
      • MinLengthAttribute 字符串最小長度驗(yàn)證

        [MinLength] 也可以用來驗(yàn)證字符串最小長度.

        驗(yàn)證 Name 屬性的字符串最小長度為 1.

          public class Test {
              [MinLength(1)]
              public string Name { get; set; }
          }
        
      • RangeAttribute 數(shù)值范圍驗(yàn)證

        [Range] 用于驗(yàn)證數(shù)值范圍.

        下面驗(yàn)證 Money 屬性的值必須在 1 到 5 之間的范圍.

          public class Test {
              [Range( 1, 5 )]
              public int Money { get; set; }
          }
        
      • EmailAddressAttribute 電子郵件驗(yàn)證

        [EmailAddress] 用于驗(yàn)證電子郵件的格式.

          public class Test {
              [EmailAddress]
              public int Email { get; set; }
          }
        
      • PhoneAttribute 手機(jī)號驗(yàn)證

        [Phone] 用于驗(yàn)證手機(jī)號的格式.

          public class Test {
              [Phone]
              public int Tel { get; set; }
          }
        
      • IdCardAttribute 身份證驗(yàn)證

        [IdCard] 用于驗(yàn)證身份證的格式.

        它是一個(gè)Util應(yīng)用框架自定義的數(shù)據(jù)注解.

          public class Test {
              [IdCard]
              public int IdCard { get; set; }
          }
        
      • UrlAttribute Url驗(yàn)證

        [Url] 用于驗(yàn)證網(wǎng)址格式.

          public class Test {
              [Url]
              public int Url { get; set; }
          }
        
      • RegularExpressionAttribute 正則表達(dá)式驗(yàn)證

        [RegularExpression] 可以使用正則表達(dá)式進(jìn)行驗(yàn)證.

        由于正則表達(dá)式比較復(fù)雜,對于經(jīng)常使用的場景,應(yīng)封裝成自定義數(shù)據(jù)注解.

        下面使用正則表達(dá)式驗(yàn)證身份證,可以封裝到 [IdCard] 數(shù)據(jù)注解,從而避免正則表達(dá)式的復(fù)雜性.

          public class Test {
              [RegularExpression( @"(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)" )]
              public string IdCard { get; set; }
          }
        

      驗(yàn)證數(shù)據(jù)注解

      雖然在對象屬性上添加了數(shù)據(jù)注解,但它們并不會(huì)自動(dòng)觸發(fā)驗(yàn)證.

      你可以使用 Asp.Net Core 提供的方法驗(yàn)證對象上的數(shù)據(jù)注解.

      Util 提供了一個(gè)輔助方法 Util.Validation.DataAnnotationValidation.Validate 用來驗(yàn)證數(shù)據(jù)注解.

      DataAnnotationValidation.Validate 方法接收一個(gè)對象參數(shù),只需將要驗(yàn)證的對象實(shí)例傳入即可.

      返回類型為驗(yàn)證結(jié)果集合,包含所有驗(yàn)證失敗的消息.

          public class Test {
              [Required]
              public string Name { get; set; }
      
              public ValidationResultCollection Validate() {
                  return DataAnnotationValidation.Validate( this );
              }
          }
      

      大部分情況下,你并不需要調(diào)用 DataAnnotationValidation.Validate 方法驗(yàn)證數(shù)據(jù)注解.

      實(shí)體,值對象,DTO等對象已經(jīng)內(nèi)置了 Validate 方法,它們會(huì)自動(dòng)驗(yàn)證數(shù)據(jù)注解.

      Util Angular UI 數(shù)據(jù)注解驗(yàn)證支持

      Util Angular UI支持 Razor TagHelper服務(wù)端標(biāo)簽語法.

      可以在表單組件使用 Lambda表達(dá)式綁定 DTO 對象屬性.

      TestDto參數(shù)對象 Name 屬性使用 [Required] 設(shè)置必填項(xiàng)驗(yàn)證.

          public class TestDto : DtoBase {
              [Required]
              [Display(Name = "name")]
              public string Name { get; set; }
          }
      

      Razor 頁面聲明 TestDto 模型, 定義輸入框 util-input,使用 for 屬性綁定到 TestDto 參數(shù)對象的 Name 屬性.

      @page
      @model TestDto
      
      <util-form>
          <util-input id="input_Name" for="Name" />
      </util-form>
      

      Razor頁面最終會(huì)生成html,表單標(biāo)簽 nz-form-label 添加了 nzRequired 必填項(xiàng)屬性, 輸入框 input 添加了 required 必填項(xiàng)屬性.

      <form nz-form>
          <nz-form-item>
              <nz-form-label [nzRequired]="true">name</nz-form-label>
              <nz-form-control [nzErrorTip]="vt_input_Name">
                  <input #input_Name="" #v_input_Name="xValidationExtend" name="name" nz-input="" x-validation-extend="" [(ngModel)]="model.name" [required]="true" />
                  <ng-template #vt_input_Name="">{{v_input_Name.getErrorMessage()}}</ng-template>
              </nz-form-control>
          </nz-form-item>
      </form>
      

      通過將DTO數(shù)據(jù)注解轉(zhuǎn)換成標(biāo)簽的驗(yàn)證屬性,可以讓 Web Api 和 UI 的驗(yàn)證同步.

      自定義驗(yàn)證

      數(shù)據(jù)注解可以解決一些常見的驗(yàn)證場景.

      但業(yè)務(wù)上可能需要編寫自定義代碼以更靈活的方式驗(yàn)證.

      Util應(yīng)用框架定義了一個(gè)驗(yàn)證接口 Util.Validation.IValidation.

      IValidation 接口定義了 Validate 方法,執(zhí)行該方法返回驗(yàn)證結(jié)果集合.

      /// <summary>
      /// 驗(yàn)證操作
      /// </summary>
      public interface IValidation {
          /// <summary>
          /// 驗(yàn)證
          /// </summary>
          ValidationResultCollection Validate();
      }
      

      實(shí)體,值對象,DTO等對象類型實(shí)現(xiàn)了 IValidation 接口,意味著這些對象可以通過標(biāo)準(zhǔn)的 Validate 方法進(jìn)行驗(yàn)證.

      var entity = new TestEntity();
      entity.Validate();
      

      不論對象內(nèi)部多么復(fù)雜,要驗(yàn)證它只需調(diào)用 Validate 方法即可.

      驗(yàn)證邏輯被完全封裝到對象內(nèi)部.

      DTO自定義驗(yàn)證

      DTO參數(shù)對象 Validate 方法默認(rèn)僅驗(yàn)證數(shù)據(jù)注解,如果有錯(cuò)誤將拋出 Warning 異常.

      Warning 異常代表業(yè)務(wù)錯(cuò)誤,它的錯(cuò)誤消息會(huì)返回給客戶端.

      Validate 是一個(gè)虛方法,可以進(jìn)行重寫.

          public class TestDto : DtoBase {
              [Required]
              public string Name { get; set; }
      
              public override ValidationResultCollection Validate() {
                  base.Validate();
                  if ( Name.Contains( "test" ) )
                      throw new Warning( "名稱不能包含test" );
                  return ValidationResultCollection.Success;
              }
          }
      

      TestDto 重寫了 Validate 方法.

      首先調(diào)用 base.Validate(); ,保證數(shù)據(jù)注解得到驗(yàn)證.

      如果數(shù)據(jù)注解驗(yàn)證通過, 判斷 Name 屬性是否包含 test 字符串,如果包含則拋出 Warning 異常.

      由于DTO參數(shù)僅用來傳遞數(shù)據(jù),不應(yīng)包含復(fù)雜的驗(yàn)證邏輯,通過重寫 Validate 方法添加簡單自定義驗(yàn)證邏輯應(yīng)能滿足需求.

      另外, DTO參數(shù)驗(yàn)證失敗,可直接拋出 Warning 異常,讓全局異常處理器進(jìn)行處理.

      領(lǐng)域?qū)ο笞远x驗(yàn)證

      領(lǐng)域?qū)ο蟀瑢?shí)體和值對象等.

      對于較復(fù)雜的業(yè)務(wù)場景,與DTO不同的是,領(lǐng)域?qū)ο罂捎糜跇I(yè)務(wù)處理,而不是傳遞數(shù)據(jù).

      需要為領(lǐng)域?qū)ο筇峁└嗟尿?yàn)證支持.

      領(lǐng)域?qū)ο笥卸喾N方式進(jìn)行自定義驗(yàn)證.

      • 重寫 Validate 方法

        領(lǐng)域?qū)ο笞詈唵蔚淖远x驗(yàn)證方式是重寫 Validate 方法,并提供額外的驗(yàn)證邏輯.

            public class TestEntity : AggregateRoot<TestEntity> {
                public TestEntity() : this( Guid.Empty ) {
                }
                public TestEntity( Guid id ) : base( id ) {
                }
        
                [Required]
                public string Name { get; set; }
        
                public override ValidationResultCollection Validate() {
                    base.Validate();
                    if( Name.Contains( "test" ) )
                        throw new Warning( "名稱不能包含test" );
                    return ValidationResultCollection.Success;
                }
            }
        

        不過重寫 Validate 驗(yàn)證方式也存在一些問題.

        • Validate 方法逐漸變得臃腫,代碼穩(wěn)定性在降低.

        • 代碼的清晰度很低,重要的驗(yàn)證條件屬于業(yè)務(wù)規(guī)則,卻被一堆雜亂的 if else 判斷淹沒了.

      • 驗(yàn)證規(guī)則

        驗(yàn)證規(guī)則 Util.Validation.IValidationRule 代表一個(gè)驗(yàn)證條件,接口定義如下.

          /// <summary>
          /// 驗(yàn)證規(guī)則
          /// </summary>
          public interface IValidationRule {
              /// <summary>
              /// 驗(yàn)證
              /// </summary>
              ValidationResult Validate();
          }
        

        可以為較復(fù)雜和重要的驗(yàn)證條件創(chuàng)建驗(yàn)證規(guī)則對象,把復(fù)雜的驗(yàn)證邏輯封裝起來,并從領(lǐng)域?qū)ο笾蟹蛛x出來.

        • 創(chuàng)建驗(yàn)證規(guī)則對象

          約定: 驗(yàn)證規(guī)則對象需要取一個(gè)符合業(yè)務(wù)驗(yàn)證規(guī)則的名稱, 并以 ValidationRule 結(jié)尾,文件放到 ValidationRules 目錄中.

          ValidationRule 結(jié)尾可能導(dǎo)致名稱過長.

          這里演示就隨便起一個(gè) SampleValidationRule.

          驗(yàn)證規(guī)則依賴一些對象才能進(jìn)行驗(yàn)證,如何才能獲取依賴?

          通過驗(yàn)證規(guī)則對象的構(gòu)造方法傳入需要的依賴對象.

          驗(yàn)證規(guī)則不通過Ioc容器管理,在需要的地方通過 new 創(chuàng)建驗(yàn)證規(guī)則實(shí)例.

          SampleValidationRule 示例構(gòu)造方法只接收一個(gè)參數(shù),但可以根據(jù)需要接收更多依賴項(xiàng).

          實(shí)現(xiàn)驗(yàn)證規(guī)則的 Validate 方法.

          如果驗(yàn)證成功返回 ValidationResult.Success.

          如果驗(yàn)證失敗返回驗(yàn)證結(jié)果對象 ValidationResult, 并設(shè)置驗(yàn)證失敗消息.

          public class SampleValidationRule : IValidationRule {
              private readonly TestEntity _entity;
          
              public SampleValidationRule( TestEntity entity ) {
                  _entity = entity;
              }
          
              public ValidationResult Validate() {
                  if( _entity.Name.Contains( "test" ) )
                      return new ValidationResult( "名稱不能包含test" );
                  return ValidationResult.Success;
              }
          }
          
        • 將驗(yàn)證規(guī)則添加到領(lǐng)域?qū)ο?/p>

          領(lǐng)域?qū)ο蠡惗x了 AddValidationRule 方法,用于添加驗(yàn)證規(guī)則對象.

          從領(lǐng)域?qū)ο笸獠空{(diào)用 AddValidationRule 傳入驗(yàn)證規(guī)則.

              var entity = new TestEntity();
              entity.AddValidationRule( new SampleValidationRule( entity ) );
          

          可以通過工廠方法封裝驗(yàn)證規(guī)則.

          public class TestEntity : AggregateRoot<TestEntity> {
              public TestEntity() : this( Guid.Empty ) {
              }
              public TestEntity( Guid id ) : base( id ) {
              }
          
              [Required]
              public string Name { get; set; }
          
              public static TestEntity Create() {
                  var entity = new TestEntity();
                  entity.AddValidationRule( new SampleValidationRule( entity ) );
                  return entity;
              }
          }
          
          var entity = TestEntity.Create();
          entity.Validate();
          

          對于比較固定且只依賴領(lǐng)域?qū)ο蟊旧淼尿?yàn)證規(guī)則,可以在構(gòu)造方法添加.

          public class TestEntity : AggregateRoot<TestEntity> {
              public TestEntity() : this( Guid.Empty ) {
              }
          
              public TestEntity( Guid id ) : base( id ) {
                  AddValidationRule( new SampleValidationRule( this ) );
              }
          
              [Required]
              public string Name { get; set; }
          }
          
        • 設(shè)置驗(yàn)證處理器

          驗(yàn)證規(guī)則僅返回驗(yàn)證結(jié)果,驗(yàn)證失敗如何處理由驗(yàn)證處理器決定.

          /// <summary>
          /// 驗(yàn)證處理器
          /// </summary>
          public interface IValidationHandler {
              /// <summary>
              /// 處理驗(yàn)證錯(cuò)誤
              /// </summary>
              /// <param name="results">驗(yàn)證結(jié)果集合</param>
              void Handle( ValidationResultCollection results );
          }
          

          領(lǐng)域?qū)ο竽J(rèn)的驗(yàn)證處理器在驗(yàn)證失敗時(shí)拋出 Warning 異常.

          你可以設(shè)置自己的驗(yàn)證處理器來替換默認(rèn)的.

          下面定義的 NothingHandler 在驗(yàn)證失敗時(shí)什么也不做.

          /// <summary>
          /// 驗(yàn)證失敗,不做任何處理
          /// </summary>
          public class NothingHandler : IValidationHandler {
              /// <summary>
              /// 處理驗(yàn)證錯(cuò)誤
              /// </summary>
              /// <param name="results">驗(yàn)證結(jié)果集合</param>
              public void Handle( ValidationResultCollection results ) {
              }
          }
          

          調(diào)用 SetValidationHandler 方法設(shè)置驗(yàn)證處理器.

          var entity = new TestEntity();
          entity.AddValidationRule( new SampleValidationRule( entity ) );
          entity.SetValidationHandler( new NothingHandler() );
          

      驗(yàn)證攔截器

      Util應(yīng)用框架定義了幾個(gè)用于驗(yàn)證的參數(shù)攔截器.

      • NotNullAttribute

        • 驗(yàn)證是否為 null,如果為 null 拋出 ArgumentNullException 異常.

        • 使用范例:

          public interface ITestService : ISingletonDependency {
              void Test( [NotNull] string value );
          }
        
      • NotEmptyAttribute

        • 使用 string.IsNullOrWhiteSpace 驗(yàn)證是否為空字符串,如果為空則拋出 ArgumentNullException 異常.

        • 使用范例:

          public interface ITestService : ISingletonDependency {
              void Test( [NotEmpty] string value );
          }
        
      • ValidAttribute

        • 如果對象實(shí)現(xiàn)了 IValidation 驗(yàn)證接口,則自動(dòng)調(diào)用對象的 Validate 方法進(jìn)行驗(yàn)證.

        • 使用范例:

          驗(yàn)證單個(gè)對象.

          public interface ITestService : ISingletonDependency {
              void Test( [Valid] CustomerDto dto );
          }
        

        驗(yàn)證對象集合.

          public interface ITestService : ISingletonDependency {
              void Test( [Valid] List<CustomerDto> dto );
          }
        

      源碼解析

      DataAnnotationValidation 數(shù)據(jù)注解驗(yàn)證操作

      可以調(diào)用 DataAnnotationValidationValidate 方法驗(yàn)證數(shù)據(jù)注解.

      /// <summary>
      /// 數(shù)據(jù)注解驗(yàn)證操作
      /// </summary>
      public static class DataAnnotationValidation {
          /// <summary>
          /// 驗(yàn)證
          /// </summary>
          /// <param name="target">驗(yàn)證目標(biāo)</param>
          public static ValidationResultCollection Validate( object target ) {
              if( target == null )
                  throw new ArgumentNullException( nameof( target ) );
              var result = new ValidationResultCollection();
              var validationResults = new List<ValidationResult>();
              var context = new ValidationContext( target, null, null );
              var isValid = Validator.TryValidateObject( target, context, validationResults, true );
              if ( !isValid )
                  result.AddList( validationResults );
              return result;
          }
      }
      

      ValidationResultCollection 驗(yàn)證結(jié)果集合

      ValidationResultCollection 用于收集驗(yàn)證結(jié)果消息.

      /// <summary>
      /// 驗(yàn)證結(jié)果集合
      /// </summary>
      public class ValidationResultCollection : List<ValidationResult> {
      
          /// <summary>
          /// 初始化驗(yàn)證結(jié)果集合
          /// </summary>
          public ValidationResultCollection() : this( "" ) {
          }
      
          /// <summary>
          /// 初始化驗(yàn)證結(jié)果集合
          /// </summary>
          /// <param name="result">驗(yàn)證結(jié)果</param>
          public ValidationResultCollection( string result ) {
              if( string.IsNullOrWhiteSpace( result ) )
                  return;
              Add( new ValidationResult( result ) );
          }
      
          /// <summary>
          /// 成功驗(yàn)證結(jié)果集合
          /// </summary>
          public static readonly ValidationResultCollection Success = new();
      
          /// <summary>
          /// 是否有效
          /// </summary>
          public bool IsValid => Count == 0;
      
          /// <summary>
          /// 添加驗(yàn)證結(jié)果集合
          /// </summary>
          /// <param name="results">驗(yàn)證結(jié)果集合</param>
          public void AddList( IEnumerable<ValidationResult> results ) {
              if( results == null )
                  return;
              foreach( var result in results )
                  Add( result );
          }
      
          /// <summary>
          /// 輸出驗(yàn)證消息
          /// </summary>
          public override string ToString() {
              if( IsValid )
                  return string.Empty;
              return this.First().ErrorMessage;
          }
      }
      

      ThrowHandler 驗(yàn)證處理器

      ThrowHandler 是默認(rèn)的驗(yàn)證處理器,在驗(yàn)證失敗時(shí)拋出 Warning 異常.

      /// <summary>
      /// 驗(yàn)證失敗,拋出異常
      /// </summary>
      public class ThrowHandler : IValidationHandler{
          /// <summary>
          /// 處理驗(yàn)證錯(cuò)誤
          /// </summary>
          /// <param name="results">驗(yàn)證結(jié)果集合</param>
          public void Handle( ValidationResultCollection results ) {
              if ( results.IsValid )
                  return;
              throw new Warning( results.First().ErrorMessage );
          }
      }
      

      ValidAttribute 驗(yàn)證攔截器

      ValidAttribute 是一個(gè) Aop 參數(shù)攔截器,可以對實(shí)現(xiàn)了 IValidation 接口的單個(gè)對象或?qū)ο蠹线M(jìn)行驗(yàn)證.

      /// <summary>
      /// 驗(yàn)證攔截器
      /// </summary>
      public class ValidAttribute : ParameterInterceptorBase {
          /// <summary>
          /// 執(zhí)行
          /// </summary>
          public override async Task Invoke( ParameterAspectContext context, ParameterAspectDelegate next ) {
              Validate( context.Parameter );
              await next( context );
          }
      
          /// <summary>
          /// 驗(yàn)證
          /// </summary>
          private void Validate( Parameter parameter ) {
              if ( Reflection.IsGenericCollection( parameter.RawType ) ) {
                  ValidateCollection( parameter );
                  return;
              }
              IValidation validation = parameter.Value as IValidation;
              validation?.Validate();
          }
      
          /// <summary>
          /// 驗(yàn)證集合
          /// </summary>
          private void ValidateCollection( Parameter parameter ) {
              if ( !( parameter.Value is IEnumerable<IValidation> validations ) )
                  return;
              foreach ( var validation in validations )
                  validation.Validate();
          }
      }
      
      posted @ 2023-11-07 08:21  何鎮(zhèn)汐  閱讀(638)  評論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 国自产拍偷拍精品啪啪一区二区| 伊人色综合一区二区三区| 精品麻豆国产色欲色欲色欲WWW| 我国产码在线观看av哈哈哈网站| 色噜噜狠狠一区二区三区果冻| 国产尤物精品自在拍视频首页| 欧美疯狂xxxxxbbbbb| 无码人妻斩一区二区三区| 国产网友愉拍精品视频手机| 日韩av无码中文无码电影| 伊人成人在线视频免费| 91老熟女老女人国产老| 色综合亚洲一区二区小说| 一本av高清一区二区三区| 高清国产一区二区无遮挡| 色综合一本到久久亚洲91| 99久久国产综合精品女图图等你| 亚洲色成人一区二区三区人人澡人人妻人人爽人人蜜桃麻豆 | 国产亚洲精品第一综合麻豆| 久久99久国产精品66| 常山县| 久久精品高清一区二区三区| 在线观看中文字幕国产码| 国产无遮挡免费真人视频在线观看| 久久三级国内外久久三级| 国产精品综合色区在线观| 中文字幕亚洲制服在线看| 亚洲精品~无码抽插| 91色老久久精品偷偷性色| 国产精品制服丝袜白丝| 国产午夜福利精品视频| 亚洲a人片在线观看网址| 久久AV中文综合一区二区| 人人玩人人添人人澡超碰| 欧美 喷水 xxxx| √天堂中文www官网在线| 久久国产精品不只是精品| 色老头亚洲成人免费影院| 中文国产不卡一区二区| 精品人妻av区乱码| 无码伊人久久大杳蕉中文无码 |