WCF Parameter Validation with Interceptor

后端 未结 2 1659
慢半拍i
慢半拍i 2020-12-08 17:58

I have a WCF service with operations that all require MyServiceRequest parameter (or derived type) and returns MyServiceResponse (or dervived type), i.e.:

           


        
2条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-08 18:13

    IParameterInspector can prevent operation from executing by throwing an exception. Here's an example.

    Define a custom fault contract:

    public class DataAccessFaultContract
    {
        public string ErrorMessage { get; set; }
    }
    

    Then the inspector:

    public class InspectorAttribute : Attribute, IParameterInspector, IOperationBehavior
    {
        public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
        {
    
        }
    
        public object BeforeCall(string operationName, object[] inputs)
        {
            MyServiceRequest request = null;
            if (inputs != null && inputs.Length > 0)
            {
                request = inputs[0] as MyServiceRequest;
            }
    
            if (request != null && request.Username != "user" && request.Password != "secret")
            {
                var fc = new DataAccessFaultContract{ ErrorMessage = "Invalid user" };
                throw new FaultException(fc);
            }
            return null;
        }
    
        public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
        {
        }
    
        public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
        {
        }
    
        public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
        {
            dispatchOperation.ParameterInspectors.Add(this);
        }
    
        public void Validate(OperationDescription operationDescription)
        {
        }
    }
    

    And finally decorate your operation with appropriate attributes:

    [ServiceContract]
    public interface IMyServiceContract
    {
        [Inspector]
        [FaultContract(typeof(DataAccessFaultContract))]
        [OperationContract]
        MySeviceResponse FindAppointments(FindAppointmentRequest request);
    
        ...
    }
    

    When invoking the service, the client could check for FaultException:

    try
    {
        var response = client.FindAppointments(request);
    }
    catch (FaultException ex)
    {
        string errorMessage = ex.Detail.ErrorMessage;
        // ...
    }
    

提交回复
热议问题