2012-08-04 27 views
5

Voy a escribir un componente de validación para usarlo en diferentes proyectos. No estoy familiarizado con ninguno de los marcos de validación como Enterprise Library VAB, Fluent, CuttingEdge.Conditions y muchos otros, sin embargo, no tengo tiempo para trabajar con todos ellos para ver cuál es mejor para mi propósito.La mejor forma de validar los valores de los parámetros del método WCF y WebService

Quiero este componente para proporcionar 2 funcionalidades diferentes para mí:

Primera, quiero tener algunos validadores como EmailValidator, StringLengthValidator, MyCustomValidator y así sucesivamente, que puedo usarlos cuando quiera en el código, como a continuación:

public class EmailValidator : RegexValidator // or StringValidator or whatever! 
{ 
    public EmailValidator() : base("emailRegexHere") 
    { 
    } 
public bool override DoValidate(string value) 
    { 
     return base.DoValidate(value); 
    } 
} 
... 

public void MyMethod(string email) 
{ 
    EmailValidator validator = new EmailValidator(); 
    if(!validator.Validate(email)) 
     throw new NotValidatedException("email is invalid."); 
    ... 
} 

Segunda, necesito para validar los parámetros mediante la aplicación de algo así como DataAnnotations a cualquier parámetro del método que yo quiero sin ningún tipo de codificación adicional. Una posible forma que conozco es escribiendo Aspectos usando PostSharp para inyectar el código donde se inicia el método (OnMethodEntry). He hecho Logging con Postsharp y funciona muy bien.

También Microsoft introduce IParameterInspector en Perform Input Validation in WCF que proporcionan 2 métodos BeforCall y AfterCall, pero creo que solo funciona para WCF.

Para terminar, tengo que hacer la validación en mi WCF o servicio Web como esto:

[System.Web.Script.Services.ScriptService] 
public class MyServiceClass : System.Web.Services.WebService 
{ 
    [Aspects.Validate] 
    [WebMethod(EnableSession = true)] 
    public string SubmitComment([Validation.Required]string content,[Validation.Guid] string userId,[Validation.Required] [Validation.Name]string name, [Validation.Email]string email, string ipAddress) 
    { 
     ... 
    } 
} 

Nota: esto es sólo un código de ejemplo para demostrar el comportamiento que necesito, alguna otra sugerencia es Bien apreciado. ¿También es una buena idea que las anotaciones de Validación * se cambien a una anotación como ValidateParam (typeof (EmailValidator))?

Gracias de antemano

Respuesta

3

Sí, me gustaría simplemente mirar a PostSharp para esto. Un OnMethodBoundaryAspect o MethodInterceptionAspect que examina los parámetros del método (para los atributos que dicen cómo validar) y los argumentos (los valores que desea validar).

Dado que ha usado OnMethodBoundaryAspect anteriormente, eche un vistazo a la documentación para MethodExecutionArgs. Puede obtener la información del método con args.Method (devuelve un MethodBase, que se encuentra en System.Reflection). Llame al GetParameters() en eso, que devuelve una matriz de ParameterInfo. En cada objeto ParameterInfo, puede obtener información sobre los atributos con la propiedad Attributes.

Una vez que conozca los atributos, sabrá qué métodos de validación usar (o si está creando sus propios atributos, el método de validación puede estar en esas clases de atributos). Entonces solo necesita usar args.Arguments para obtener los valores de los argumentos.

Aquí hay algunos (pseudo) Código:

Eso no es verdadero código: los detalles que tienen que trabajar fuera usted mismo.

Me gusta la idea de poner el código de validación en los atributos en sí, porque no tendrá que cambiar el aspecto para agregar tipos de validación adicionales.

+1

Eso es exactamente lo que tenía en mente, y casi termino de codificar. Encontré esta [publicación] (http://badecho.com/2011/11/validating-method-parameters-with-postsharp) de Matt Weber que fue útil (la primera parte). Acerca de poner el código de validación en los atributos, agregué un método de interfaz 'GetValidator', por lo que cada atributo devuelve su validador apropiado. El problema que estoy enfrentando es para validadores genéricos como 'RangeValidator', ya que C# no admite atributos genéricos, tengo que escribir una sobrecarga de constructor para cada tipo como int, double, datetime ... – Ashkan

+1

gracias por cierto! su respuesta me hizo sentir mejor acerca de este enfoque. También estoy escribiendo mis validadores con FluentValidation. Creo que es bastante bueno. – Ashkan

Cuestiones relacionadas