2

我想使用自定義的DataAnnotationsAttribute來驗證我的模型的DTO屬性上的各種電話號碼屬性。我不想將DataAnnotations複製到ViewModels上,以保持代碼乾爽,而是使用DataAnnotationsModelValidatorProvider爲客戶端驗證註冊了自定義適配器。此適配器提供了RemoteClientValidationRemoteRules,通常由RemoteAttribute使用。 jQuery unobtrusive驗證然後調用我的驗證操作,驗證單個字段。使用DataAnnotationsModelValidator適配器MVC3遠程驗證

但是,這種設置並不是很合適。

  1. 該屬性當前使用其ContainerType來確定要調用哪個 驗證操作。 DTO用於不同的視圖模型 不同級別的嵌套,但是,所以我們並不知道在動作上使用哪些前綴。根據ProfileDto 模型層次結構的位置,動作前綴將需要改變

  2. 驗證操作使用Request.Form.Keys去尋找哪些 財產應驗證。我知道這是最好的做法,以 遠離在行動Request對象離開單位 測試等的緣故

是否有包含的字段的名稱回發來驗證的好方法,所以我可以將它作爲一個附加參數而不是使用Request.Form?

有沒有辦法讓模型聯編程序綁定我的屬性,因爲他們會回發一個依賴於子模型名稱的前綴?

在此先感謝!


屬性如下:

public class PhoneNumberAttribute : ValidationAttribute 
{ 
    public PhoneNumberType RequiredType { get; set; } 

    public PhoneNumberAttribute() 
     : base("{0} is not a valid phone number.") 
    { 
    } 

    public override bool IsValid(object value) 
    { 
     string s = value as string; 
     if (s == null) 
     { 
      return false; 
     } 
     if (!PhoneNumberUtils.IsValidNumber(s, RequiredType)) 
     { 
      return false; 
     } 

     return true 
    } 

    public override string FormatErrorMessage(string name) 
    { 
     return string.Format(ErrorMessageString, name); 
    } 
} 

和適配器:

public class PhoneNumberAttributeAdapter : DataAnnotationsModelValidator<PhoneNumberAttribute> 
{ 
    public PhoneNumberAttributeAdapter(ModelMetadata metadata, ControllerContext context, PhoneNumberAttribute attribute) 
     : base(metadata, context, attribute) 
    { 
    } 

    public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() 
    { 
     var errorMessage = Attribute.FormatErrorMessage(Metadata.GetDisplayName()); 
     var routeData = new RouteValueDictionary { 
      { "controller", "Validate" }, 
      { "action", Metadata.ContainerType.Name }, 
     }; 

     var path = RouteTable.Routes.GetVirtualPathForArea(ControllerContext.RequestContext, routeData); 

     var rule = new ModelClientValidationRemoteRule(
      errorMessage, 
      path.VirtualPath, 
      "POST", 
      "*." + Metadata.PropertyName); 

     return new[] { rule }; 
    } 
} 

這裏是動作:

public ActionResult ProfileDto([Bind(Prefix = "Dto")]ProfileDto model) 
{ 
    string fieldToValidate = Request.Form.Keys[0]; 
    if (ModelState.IsValidField(fieldToValidate)) 
    { 
     return Json(true); 
    } 

    var fieldErrors = ModelState[fieldToValidate].Errors; 

    return Json(fieldErrors.First().ErrorMessage); 
} 

回答

0

看看這個例子here在哪裏顯示如何o甚至在自定義jQuery驗證器中使用前綴獲取嵌套屬性。

其次,MVC模型綁定器應該自動綁定您的前綴。