0

IClientMessageInspector で操作のログを記録する必要があり、操作がいつ開始され、いつ終了したかを知ることが重要です。ただし、一方向の操作では AfterReceiveReply を取得できません。その理由は明らかです。操作が BeforeSendRequest オーバーロードで一方向であることを知る方法はありますか?

4

2 に答える 2

1

私がこれをしている瞬間、自分自身に返信してください:

bool isOneWay = request.Headers.ReplyTo == null;

于 2012-05-01T09:31:51.097 に答える
1

インスペクター自体 (または BeforeSendRequest に渡されたメッセージ) に関する情報はありませんが、この情報をインスペクターに渡し、メッセージ アクションを使用して操作が一方向かどうかを確認できます。

public class StackOverflow_10354828
{
    [ServiceContract]
    public interface ITest
    {
        [OperationContract]
        string Echo(string text);
        [OperationContract(IsOneWay = true)]
        void Process(string input);
    }
    public class Service : ITest
    {
        public string Echo(string text)
        {
            return text;
        }
        public void Process(string input) { }
    }
    class MyInspector : IClientMessageInspector
    {
        public HashSet<string> oneWayActions;

        public MyInspector(ServiceEndpoint endpoint)
        {
            this.oneWayActions = new HashSet<string>();
            foreach (var operation in endpoint.Contract.Operations)
            {
                if (operation.IsOneWay)
                {
                    oneWayActions.Add(operation.Messages[0].Action);
                }
            }
        }

        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
            Console.WriteLine("In AfterReceiveReply");
        }

        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            Console.WriteLine("In BeginSendRequest");
            if (this.oneWayActions.Contains(request.Headers.Action))
            {
                Console.WriteLine("This is a one-way operation");
            }

            return null;
        }
    }
    class MyBehavior : IEndpointBehavior
    {
        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            clientRuntime.MessageInspectors.Add(new MyInspector(endpoint));
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
        }

        public void Validate(ServiceEndpoint endpoint)
        {
        }
    }
    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "");
        host.Open();
        Console.WriteLine("Host opened");

        ChannelFactory<ITest> factory = new ChannelFactory<ITest>(new BasicHttpBinding(), new EndpointAddress(baseAddress));
        factory.Endpoint.Behaviors.Add(new MyBehavior());
        ITest proxy = factory.CreateChannel();
        proxy.Echo("Hello");
        Console.WriteLine();

        proxy.Process("world");
        Console.WriteLine();

        ((IClientChannel)proxy).Close();
        factory.Close();

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}
于 2012-04-27T23:16:19.320 に答える