如何在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"];
    }

,但在传出请求期间,似乎OperationContext。电流是空的,所以我不能用这个。知道怎么得到它吗?知道如何干净利落地完成它(与之相反的是,解析SOAP xml)吗?

从评论你问如何做到这一点可以用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();
            }
        }
    }
}

它应该给出如下输出:

  Calling operation:DoSomthing 
  Called:hi 
  Completed operation:DoSomthing
  Press ENTER to close the host.

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

var action = reply.Headers.Action.Substring(reply.Headers.Action.LastIndexOf("/", StringComparison.OrdinalIgnoreCase) + 1);

var action = request.Headers.Action.Substring(request.Headers.Action.LastIndexOf("/", StringComparison.OrdinalIgnoreCase) + 1);

相关内容

  • 没有找到相关文章

最新更新