在发送请求和/或回复之前将数据传递给拦截器

时间:2014-01-23 04:15:19

标签: c# wcf interceptor

我正在使用消息拦截器,我想将数据从我的服务方法传递到拦截器(即到BeforeSendRequest和BeforeSendReply)。但是,我无法弄清楚如何做到这一点。

到目前为止,我所做的是我在服务执行期间设置的静态变量,然后在拦截器执行时获取。这项工作正常,除非同时发送多条消息,其中一条消息将覆盖其他消息的值!

1 个答案:

答案 0 :(得分:1)

最简单的例子是使用消息属性:

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel;

namespace SO21299236
{
    class Program
    {
        static void Main(string[] args)
        {
            var address = new Uri("net.pipe://localhost/" + Guid.NewGuid());
            var service = new ServiceHost(typeof (MyService));
            var binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
            var ep = service.AddServiceEndpoint(typeof(IMyService), binding, address);
            ep.Behaviors.Add(new MyBehavior() );
            service.Open();

            var factory = new ChannelFactory<IMyService>(binding, new EndpointAddress(address));
            var proxy = factory.CreateChannel();
            proxy.DoSomething();

            Console.WriteLine("Done.");
        }
    }

    internal class MyBehavior : IEndpointBehavior
    {
        public void Validate(ServiceEndpoint endpoint)
        {
        }

        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new CustomMessageInspector());
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
        }
    }

    internal class CustomMessageInspector : IDispatchMessageInspector
    {
        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            return null;
        }

        public void BeforeSendReply(ref Message reply, object correlationState)
        {
            var prop = reply.Properties.FirstOrDefault(z => z.Key == "MyProperty");
            Console.WriteLine(prop.Value);
        }
    }

    [ServiceContract]
    interface IMyService
    {
        [OperationContract]
        void DoSomething();
    }

    class MyService : IMyService
    {
        public void DoSomething()
        {
            OperationContext.Current.OutgoingMessageProperties.Add("MyProperty", 1);
        }
    }
}