WCF фильтр сообщений.
От: Uzzy Россия  
Дата: 14.09.11 22:08
Оценка:
Здравствуйте.

Есть задача: на стороне WCF сервиса перед вызовом контрактного метода проверять внутреннее состояние сервиса (температура, влажность, давление, чувство юмора) и, в случае провала проверки, кидать FaultException<ServerStateError>

Имеем

    [DataContract]
    public enum ServerState
    {
        [EnumMember]Normal,
        [EnumMember]Abnormal,
    }

    [DataContract]
    public sealed class ServerStateError
    {
        [DataMember]
        public readonly ServerState State;

        public ServerStateError(ServerState state)
        {
            State = state;
        }
    }


Также имеется попытка решения задачи следующим способом

Проверочка:

    public sealed class ServerStateValidator
    {
        private readonly ServerTools _tools;
        private static readonly ServerStateValidator Instance = new ServerStateValidator();

        private ServerStateValidator()
        {
            _tools = ServerTools.GetInstance();
        }

        public static void Validate()
        {
            if (Instance._tools.ServerState != ServerState.Normal)
            {
                throw new FaultException<ServerStateError>(new ServerStateError(Instance._tools.ServerState), "State error");
            }
        }
    }


Определяем OperationInvoker


    public sealed class ServiceStateValidatedOperationInvoker : IOperationInvoker
    {
        private readonly IOperationInvoker _invoker;

        public ServiceStateValidatedOperationInvoker(IOperationInvoker invoker)
        {
            _invoker = invoker;
        }

        object[] IOperationInvoker.AllocateInputs()
        {
            return _invoker.AllocateInputs();
        }

        object IOperationInvoker.Invoke(object instance, object[] inputs, out object[] outputs)
        {
            ServerStateValidator.Validate();
            return _invoker.Invoke(instance, inputs, out outputs);
        }

        IAsyncResult IOperationInvoker.InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state)
        {
            throw new NotImplementedException();
        }

        object IOperationInvoker.InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
        {
            throw new NotImplementedException();
        }

        bool IOperationInvoker.IsSynchronous
        {
            get
            {
                return true;
            }
        }
    }



OperationBehavior

    public sealed class ServiceStateValidatedOperationBehavior : IOperationBehavior
    {
        void IOperationBehavior.AddBindingParameters(
            OperationDescription operationDescription, 
            BindingParameterCollection bindingParameters)
        {
        }

        void IOperationBehavior.ApplyClientBehavior(
            OperationDescription operationDescription, 
            ClientOperation clientOperation)
        {
        }

        void IOperationBehavior.ApplyDispatchBehavior(
            OperationDescription operationDescription, 
            DispatchOperation dispatchOperation)
        {
            dispatchOperation.Invoker = new ServiceStateValidatedOperationInvoker(dispatchOperation.Invoker);
        }

        void IOperationBehavior.Validate(OperationDescription operationDescription)
        {
        }
    }



И применение Behavior


                _host = new ServiceHost(_serviceInstance, serviceUri);
                _host.Description.Behaviors.Add(new ServiceValidationBehavior());
                foreach (ServiceEndpoint endpoint in _host.Description.Endpoints)
                {
                    foreach (OperationDescription description in endpoint.Contract.Operations)
                    {
                        description.Behaviors.Add(new ServiceStateValidatedOperationBehavior());
                    }
                }



Код в целом выполняет свои задачи, кроме одной проблемки. К клиенту приходит просто FaultException, а не FaultException<ServerStateError>

Собственно вопрос, как доставить до клиента FaultException<ServerStateError> ?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.