将IOperationBehavior实现为属性

时间:2017-07-21 12:31:30

标签: c# wcf

我有一个wcf服务,我的界面看起来像这样:

[ServiceContract]
public interface IMyService 
{
    [OperationContract]
    [AllowedFileExtension]
    void SaveFile(string fileName);
}

我的目标是检查传入的消息以验证fileName。所以我的AllowedFileExtensionAttribute类看起来像这样:

 public class AllowedFileExtensionsAttribute : Attribute, IOperationBehavior
 {
        private readonly string _callingMethodName;
        private readonly string[] _allowedFileExtension;

        public AllowedFileExtensionsAttribute([CallerMemberName]string callingMethodName = null)
        {
            _callingMethodName = callingMethodName;
        }

        public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
        {

        }

        public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
        {

        }

        public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
        {

        }

        public void Validate(OperationDescription operationDescription)
        {

        }
}

从例如WCF测试客户端或简单的控制台应用程序调用它,我的Attribute类不会被调用,而是直接进入实现。我在这里做错了什么?

1 个答案:

答案 0 :(得分:2)

您可以使用WCF MessageInspector拦截请求并执行您想要执行的操作。

  

消息检查器是一个可扩展性对象,可以在服务模型的客户端运行时和调度运行时以编程方式或通过配置使用,并且可以在收到消息之后或发送消息之前检查和更改消息。

您可以实现IDispatchMessageInspectorIClientMessageInspector接口。读取AfterReceiveRequest中的传入数据,将其存储在threadstatic变量中,如果需要,请在BeforeSendRequest中使用它。

在管道中收到消息时,调度程序将调用

AfterReceiveRequest。您可以操作此请求作为参考参数传递。

请参阅msdn doc

public class SimpleEndpointBehavior : IEndpointBehavior
{
    public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
    {
        clientRuntime.MessageInspectors.Add(
            new SimpleMessageInspector()
            );
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
    { 
    }
    public void Validate(ServiceEndpoint endpoint)
    {
    }
}



public class SimpleMessageInspector : IClientMessageInspector, IDispatchMessageInspector    
{
        public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)    
        {
        }     

        public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)    
        {    

            //modify the request send from client(only customize message body)

            request = TransformMessage2(request);

            //you can modify the entire message via following function

            //request = TransformMessage(request);    

            return null;    
        }   

}

查看this post了解详情。