如何在IClientMessageInspector中获取调用的操作名称?

Lou*_*hys 6 .net c# wcf soap iclientmessageinspector

IClientMessageInspector在我的应用程序中实现了"拦截"传出Web服务调用.是否有可能找出哪些操作正在从内部被称为BeforeSendRequestAfterReceiveReply

这里有一个类似的问题,如何在WCF消息检查器中获取调用的操作名称,该命令用于服务器端(接收请求的一方).我尝试做类似的事情,例如

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        var v = OperationContext.Current.OutgoingMessageProperties["HttpOperationName"];
        return null;
    }

    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
        var v = OperationContext.Current.OutgoingMessageProperties["HttpOperationName"];
    }
Run Code Online (Sandbox Code Playgroud)

但在传出请求期间,似乎OperationContext.Current为null,所以我不能使用它.知道如何获得它吗?知道怎么干净利落(相反,解析SOAP xml)?

Ern*_*ieL 5

从您询问如何使用IParameterInspector完成此操作的评论中。操作名称是 Before/AfterCall 方法的一部分。

只是为了添加我对使用哪个检查员的评论。来自Carlos Figueira 的博客

本系列的前一篇文章中描述的消息检查器允许您完全控制通过 WCF 堆栈的消息。它们非常强大,但是您必须知道如何处理 Message 对象,这不是最理想的编程方式。如果 WCF 中的服务模型通过允许我们根据强类型操作(即使用漂亮的原始类型和用户定义类型)定义我们的服务来隐藏所有消息传递框架,那么应该有一种方法来拦截请求/响应从传入消息中(或在将它们打包到传出消息中之前)提取这些参数的处理完成。IParameterInspector 就是这样——在每次调用之前和之后,检查器有机会检查操作的输入、输出和返回值,

这是一个完整的命令行程序,它演示了:

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;

namespace WCFClientInspector
{
    public class OperationLogger : IParameterInspector
    {
        public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
        {
            Console.WriteLine("Completed operation:" + operationName);
        }

        public object BeforeCall(string operationName, object[] inputs)
        {
            Console.WriteLine("Calling operation:" + operationName);
            return null;
        }
    }

    public class OperationLoggerEndpointBehavior : IEndpointBehavior
    {
        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            foreach (ClientOperation operation in clientRuntime.ClientOperations)
            {
                operation.ClientParameterInspectors.Add(new OperationLogger());
            }
        }

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

        public void Validate(ServiceEndpoint endpoint)
        {
        }
    }


    [ServiceContract]
    public interface ISimple
    {
        [OperationContract]
        void DoSomthing(string s);
    }

    public class SimpleService : ISimple
    {
        public void DoSomthing(string s)
        {
            Console.WriteLine("Called:" + s);
        }
    }

    public static class AttributesAndContext
    {
        static void Main(string[] args)
        {
            ServiceHost simpleHost = new ServiceHost(typeof(SimpleService), new Uri("http://localhost/Simple"));
            simpleHost.Open();

            ChannelFactory<ISimple> factory = new ChannelFactory<ISimple>(simpleHost.Description.Endpoints[0]);
            factory.Endpoint.EndpointBehaviors.Add(new OperationLoggerEndpointBehavior());
            ISimple proxy = factory.CreateChannel();

            proxy.DoSomthing("hi");

            Console.WriteLine("Press ENTER to close the host.");
            Console.ReadLine();

            ((ICommunicationObject)proxy).Shutdown();

            simpleHost.Shutdown();
        }
    }

    public static class Extensions
    {
        static public void Shutdown(this ICommunicationObject obj)
        {
            try
            {
                obj.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Shutdown exception: {0}", ex.Message);
                obj.Abort();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

它应该给出输出:

  Calling operation:DoSomthing 
  Called:hi 
  Completed operation:DoSomthing
  Press ENTER to close the host.
Run Code Online (Sandbox Code Playgroud)


Pio*_*app 4

reply.Headers.Action和呢request.Headers.Action?当然,其余的与所链接的问题一样棘手。所以完整的代码将是:

var action = reply.Headers.Action.Substring(reply.Headers.Action.LastIndexOf("/", StringComparison.OrdinalIgnoreCase) + 1);
Run Code Online (Sandbox Code Playgroud)

或者

var action = request.Headers.Action.Substring(request.Headers.Action.LastIndexOf("/", StringComparison.OrdinalIgnoreCase) + 1);
Run Code Online (Sandbox Code Playgroud)

  • 奇怪..当我测试此代码时 `request.Headers.Action` 是一个空字符串 `""` 并且 `reply.Headers.Action` 为 null (4认同)