2016-04-05 78 views
2

所以我一直在這裏撞牆。我跟着教程去了這封信,我沒有意識到爲什麼這個自定義驗證不起作用。它應該驗證電話號碼。MVC 5自定義驗證屬性未觸發

的去縮短到年底

自定義屬性:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] 
public sealed class CustomPhoneAttribute : DataTypeAttribute, IClientValidatable 
{ 
    private static readonly string[] ddds = new[] { ... }; 

    private static Regex regex = new Regex(@"^(\([0-9]{2}\)) ([0-9]{5}-[0-9]{4}|[0-9]{4}-[0-9]{4}$", RegexOptions.Compiled); 

    private const string DefaultErrorMessage = "{0} must be a phone number."; 

    public CustomPhoneAttribute() 
     : base(DataType.PhoneNumber) 
    { 
     ErrorMessage = DefaultErrorMessage; 
    } 

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

    private bool ValidatePhone(string phone) 
    { 

     if (regex.Match(phone).Success) 
     { 
      var ddd = phone.Substring(1, 2); 

      if (ddds.Contains(ddd)) 
      { 
       var phoneParts = phone.Substring(5).Split('-'); 
      } 

      // TODO: perform further evaluation base on 
      // ddd, first digit and extra 9. 
      // For now we only check the ddd exists. 

      return true; 
     } 

     return false; 
    } 

    public override bool IsValid(object value) 
    { 
     if (value == null) 
     { 
      return true; 
     } 

     return ValidatePhone((string)value); 
    } 

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     yield return new ModelClientValidationRule() 
     { 
      ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()), 
      ValidationType = "brphone" 
     }; 

    } 

型號:

{...} 

[CustomRequired] // this works. 
[DataType(DataType.PhoneNumber)] 
[Display(Name = "Phone")] 
[CustomPhone] 
public string Phone { get; set; } 

{...} 

的Javascript:

$.validator.addMethod("brphone", 

function (value, element) { 

    if (!this.optional(element)) { 

     // perform validation. 
     return true; 
    } 

    return true; 
}); 

$.validator.unobtrusive.adapters.addBool("brphone"); 

查看:

@Html.TextBoxFor(m => m.Phone, new { @class = "form-control phonemask-client", placeholder = "(xx) xxxxx-xxxx" }) 

一切似乎都查出來,還沒有服務器端,也沒有客戶端驗證工作。 IT OUT(來自微軟可能是BUG)

想通PART

如果我從數據註解類中刪除的正則表達式對象,它就像一個魅力。現在,爲什麼會發生這種情況,我不知道!如果我附加了一個調試器,當它碰到正則表達式聲明並且點擊繼續調試時,程序就會返回到網頁並且什麼也沒有發生。

是否禁止在數據註釋中使用正則表達式?

回答

1

您在正則表達式中缺少括號,當該屬性被實例化時會導致錯誤。

// missing ')' between the {4} and $ 
private static Regex regex = new Regex(@"^(\([0-9]{2}\)) ([0-9]{5}-[0-9]{4}|[0-9]{4}-[0-9]{4})$", RegexOptions.Compiled); 

由於字段上的static關鍵字,我們在運行時看不到錯誤。

讓我們假設你的屬性是這樣的:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] 
public sealed class CustomPhoneAttribute : DataTypeAttribute 
{ 
    public static string MyString = GetValue(); 

    public CustomPhoneAttribute() 
     : base(DataType.PhoneNumber) 
    { 
    } 

    private static string GetValue() 
    { 
     throw new Exception(); 
    } 

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     return base.IsValid(value, validationContext); 
    } 
} 

當使用static關鍵字,運行時需要自身實例化的類前需要初始化時間在一些點式電平值。但是,發生這種情況時會導致崩潰,因爲GetValue代碼引發異常。當MVC查看數據註釋的模型時,會發生該錯誤,並且它將繼而忽略該屬性(因爲它未能實例化)。

通過刪除static關鍵字,當註解被實例化時,會導致在構造函數中拋出錯誤,所以它首先在您的代碼中拋出,並且調試器可以中斷它。

+0

我在回答時輸入了我的答案。男人,因爲這個愚蠢的設計而失去了幾個小時的工作。我怎麼沒有在自己的代碼中遇到異常?順便說一句,我嘗試刪除靜態,它仍然沒有拋出異常(使用mvc 5)。我不得不嘗試從另一個DLL執行它來獲取異常。 – victor

+1

我錯在編譯時錯誤,它總是在運行時。我會更新我的答案以糾正錯誤,並添加一個示例來幫助解釋爲什麼我們在運行時沒有看到靜態字段的異常。 –

0

已解決。 問題出在正則表達式中。它錯過了一個關閉「)」。可笑的是,我沒有得到例外。

所以:

@"^(\([0-9]{2}\)) ([0-9]{5}-[0-9]{4}|[0-9]{4}-[0-9]{4}$" 

成爲

@"^(\([0-9]{2}\)) ([0-9]{5}-[0-9]{4}|[0-9]{4}-[0-9]{4})$" 

找出例外,我不得不實施在另一個項目註釋。作爲圖書館。 然後,我將dll添加到當前項目中,並嘗試使用它。我有一個黃頁,說我的正則表達式是錯誤的。

這個異常應該從我自己的代碼中拋出,嗯。