2016-04-05 13 views
2

Also habe ich meinen Kopf gegen die Wand hier schlug. Ich habe die Tutorials genau verfolgt und habe keine Ahnung, warum diese benutzerdefinierte Validierung nicht funktioniert. Es soll Telefonnummern validieren.MVC 5 benutzerdefinierte Validierung Attribut nicht ausgelöst

für kürzere gehen bis zum Ende

Benutzerdefinierte Attribut:

[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" 
     }; 

    } 

Modell:

{...} 

[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"); 

Ausblick:

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

Alles scheint zu überprüfen, noch weder Server-Seite noch Clientseite Validierung funktioniert.

beziffern TEIL DAVON OUT (möglicherweise Fehler von Microsoft)

Wenn ich das Regex-Objekt aus den Daten Annotation-Klasse entfernen, es funktioniert wie ein Charme. Nun, warum das passiert, ich habe keine Ahnung! Wenn ich einen Debugger anschließe, wenn er auf die Regex-Deklaration trifft und ich auf "Weiter" klicke, um mit dem Debuggen fortzufahren, kehrt das Programm einfach zur Webseite zurück und nichts passiert.

Ist es verboten, Regex in einer Datenannotation zu verwenden?

Antwort

1

Ihnen fehlen in Ihrem regulären Ausdruck Klammern, die bei der Instanziierung des Attributs einen Fehler verursachen.

// 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); 

Wir haben keine Fehler zur Laufzeit aufgrund des static Schlüsselwort auf dem Feld sehen.

Stellen wir uns vor, dass Ihr Attribut sah wie folgt aus:

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

Wenn das Stichwort static verwenden, müssen die Laufzeit der Typ-Level-Werte zu einem bestimmten Zeitpunkt in der Zeit vor der Klasse initialisieren selbst instanziiert . Wenn dies jedoch geschieht, führt dies zu einem Absturz, da der Code GetValue eine Ausnahme auslöst. Dieser Fehler tritt auf, wenn MVC das Modell für Datenanmerkungen betrachtet und dieses Attribut ignoriert (da es nicht instanziiert wurde).

Wenn Sie das Schlüsselwort static entfernen, wird der Fehler in Ihrem Konstruktor ausgelöst, wenn die Annotation instanziiert wird. Sie wird also zuerst in den Code eingefügt, und der Debugger kann den Fehler beheben.

+0

Ich tippte meine Antwort, als Sie antworteten. Mann, wegen dieses blöden Designs habe ich nur Stunden Arbeit verloren. Wieso habe ich in meinem eigenen Code keine Ausnahme bekommen? Btw, ich habe versucht, die statische zu entfernen, und es hat immer noch nicht die Ausnahme für mich (mit MVC 5). Ich musste versuchen, es von einer anderen DLL auszuführen, um die Ausnahme zu erhalten. – victor

+1

Ich war falsch über den Kompilierungsfehler, es wird immer zur Laufzeit sein. Ich werde meine Antwort aktualisieren, um dies zu korrigieren, und ein Beispiel hinzufügen, um zu erläutern, warum die Ausnahme für ein statisches Feld zur Laufzeit nicht angezeigt wird. –

0

Gelöst. Problem war in der Regex. Es fehlte ein abschließendes ")". Lächerlich genug, ich habe dafür keine Ausnahme bekommen.

So:

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

wird

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

Um die Ausnahme herauszufinden, ich die Anmerkung in einem anderen Projekt umsetzen mussten. als Bibliothek. Dann fügte ich die DLL zu meinem aktuellen Projekt hinzu und versuchte es zu benutzen. Ich habe eine gelbe Seite, auf der steht, dass meine Regex falsch ist.

Diese Ausnahme sollte aus meinem eigenen Code geworfen haben, meh.

Verwandte Themen