2011-12-08 13 views
14

Gestionamos varios sitios web del cliente ASP.NET MVC, que todos utilizan una anotación de datos como el siguiente para validar las direcciones de correo electrónico del cliente (no he incluido aquí la expresión regular, para facilitar la lectura):¿Cómo puedo establecer un argumento de expresión regular de la anotación de datos de RegularExpression en el tiempo de ejecución?

[Required(ErrorMessage="Email is required")] 
[RegularExpression(@"MYREGEX", ErrorMessage = "Email address is not valid")] 
public string Email { get; set; } 

Lo que lo que queremos hacer es centralizar esta expresión regular, de modo que si hacemos un cambio en ella, todos los sitios la recogen inmediatamente y no tenemos que cambiarla manualmente en cada uno.

El problema es que el argumento regex de la anotación de datos debe ser una constante, por lo que no puedo asignar un valor que he recuperado de un archivo de configuración o base de datos en tiempo de ejecución (que fue mi primera idea).

¿Alguien me puede ayudar con una solución inteligente para esto o, en su defecto, un enfoque alternativo que funcione para lograr el mismo objetivo? ¿O esto solo requiere que escribamos un atributo de validación personalizado especialista que aceptará valores no constantes?

+0

[correo electrónico regular la expresión MVC C#] (http://lesson8.blogspot.com/2013/03/email-regular-expression-mvc-c.html) – Sender

+1

'[EmailAddress (ErrorMessage = "No es una dirección de correo electrónico válida")] 'ya está incluida en' System.ComponentModel.DataAnnotations.dll' –

Respuesta

26

La forma más fácil es escribir una costumbre ValidationAttribute que hereda de RegularExpressionAttribute, así que algo como:

public class EmailAttribute : RegularExpressionAttribute 
    { 
     public EmailAttribute() 
      : base(GetRegex()) 
     { } 

     private static string GetRegex() 
     { 
      // TODO: Go off and get your RegEx here 
      return @"^[\w-]+(\.[\w-]+)*@([a-z0-9-]+(\.[a-z0-9-]+)*?\.[a-z]{2,6}|(\d{1,3}\.){3}\d{1,3})(:\d{4})?$"; 
     } 
    } 

De esta manera, aún mantiene el uso de la incorporada en la validación de expresiones regulares, pero se puede personalizar.Se podría simplemente usarlo como:

[Email(ErrorMessage = "Please use a valid email address")] 

Por último, para llegar a la validación del lado del cliente para trabajar, sólo tendría que añadir lo siguiente en su método de Application_Start dentro Global.asax, a decir MVC usar la validación de expresiones regulares normales para este validador:

DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(EmailAttribute), typeof(RegularExpressionAttributeAdapter)); 
+0

Estoy aceptando esto porque Era una solución simple y completa, bien explicada. ¡Gracias! –

+0

Gracias Marcar y sin preocupaciones, ¡me alegro de que haya sido útil! –

+0

Esto retrocede un tiempo, pero ¿alguien puede explicar cómo obtuvieron su expresión regular del archivo de recursos? Puedo obtener los idiomas esperados en mi modelo (por ejemplo, para el mensaje de error) pero siempre obtengo la expresión regular para el archivo '.resx' predeterminado de la extensión cuando se usa arriba. ¿Algunas ideas? –

3

¿Realmente desea poner la expresión regular en el archivo de base de datos/configuración, o simplemente desea centralizarlos? Si lo que desea es poner la expresión regular en conjunto, sólo puede definir y utilizar constantes como

public class ValidationRegularExpressions { 
    public const string Regex1 = "..."; 
    public const string Regex2 = "..."; 
} 

Tal vez desea administrar las expresiones regulares en archivos externos, se puede escribir una tarea MSBuild hacer la sustitución cuando se genera para producción.

Si realmente desea cambiar la expresión regular de validación en tiempo de ejecución, definir su propio ValidationAttribute, como

[RegexByKey("MyKey", ErrorMessage = "Email address is not valid")] 
public string Email { get; set; } 

que es sólo un pedazo de código para escribir:

public class RegexByKeyAttribute : ValidationAttribute { 
    public RegexByKey(string key) { 
     ... 
    } 

    // override some methods 
    public override bool IsValid(object value) { 
     ... 
    } 
} 

O incluso:

public class RegexByKeyAttribute : RegularExpressionAttribute { 
    public RegexByKey(string key) : base(LoadRegex(key)) { } 

    // Be careful to cache the regex is this operation is expensive. 
    private static string LoadRegex(string key) { ... } 
} 

espero que sea útil: http://msdn.microsoft.com/en-us/library/cc668224.aspx

Cuestiones relacionadas