Mar 1, 2012

WCF error handling using DataAnnotations Validator

ParameterInspector can also be used to validate DataMember in the data contract for the incoming request by using DataAnnotations Validator.

So suppose I have a DataContract defined something like this

 [DataContract]
    public class CompositeType
    {
        string stringValue = "Hello ";
        [DataMember]
        [Required(ErrorMessage = "Name is required")]
        [StringLength(20, MinimumLength = 1, ErrorMessage = "Name must have between 1 and 20 characters")]
        public string StringValue
        {
            get { return stringValue; }
            set { stringValue = value; }
        }
    }

Refer to DataAnnotations Required and StringLength attribute. Now I want a generic Validator which inspects the parameter and does Validation using DataAnnotations.

 
 public class ValidatingParameterInspector : IParameterInspector
    {
        public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState){}
  
        public object BeforeCall(string operationName, object[] inputs)
        {
   //So I loop through all the input parameters and validate it using DataAnnotations Validator
            foreach (var input in inputs)
            {
                if (input != null)
                {
                    ValidationContext context = new ValidationContext(input, null, null);
                    Validator.ValidateObject(input, context, true);
                }
            }
            return null;
        }
    }
And now you can add this to OperationBehavior or even endpoint behavior
 

 public class ValidatingParameterInspectorOperationBehavior : Attribute, IOperationBehavior
    {
        public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation){}
        public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters){}
        public void Validate(OperationDescription operationDescription){}
        public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
        {
            ValidatingParameterInspector validatingParameterInspector = new ValidatingParameterInspector();
            dispatchOperation.ParameterInspectors.Add(validatingParameterInspector);
        }
    } 
So now before call reaches to the operation it will be inspected by BeforeCall where it will fail validation and raise exception. You can also raise custom FaultException

No comments:

Post a Comment