Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wcf 为单个操作启用SOAP消息检查_Wcf - Fatal编程技术网

Wcf 为单个操作启用SOAP消息检查

Wcf 为单个操作启用SOAP消息检查,wcf,Wcf,如何强制IMessageInspector仅在调用特定操作时启动,而不是在调用服务时启动?目前,我正在将自定义的IEndpointBehavior应用于调用此IMessageInspector的端点,但这并不完全是我想要做的…消息检查器绑定到调度运行时对象,该对象是每个端点的单一对象,而不是操作。如果参数检查器工作,则可以使用它(它绑定到操作),但如果需要消息检查器,则无法将其绑定到单个操作。但是,您可以在inspector内部检查操作是否符合预期(基于操作头,每个操作都是唯一的),如下面的代码

如何强制
IMessageInspector
仅在调用特定操作时启动,而不是在调用服务时启动?目前,我正在将自定义的
IEndpointBehavior
应用于调用此
IMessageInspector
的端点,但这并不完全是我想要做的…

消息检查器绑定到调度运行时对象,该对象是每个端点的单一对象,而不是操作。如果参数检查器工作,则可以使用它(它绑定到操作),但如果需要消息检查器,则无法将其绑定到单个操作。但是,您可以在inspector内部检查操作是否符合预期(基于操作头,每个操作都是唯一的),如下面的代码所示

public class StackOverflow_7502134
{
    [ServiceContract]
    public interface ITest
    {
        [OperationContract]
        string Echo(string text);
        [OperationContract]
        int Add(int x, int y);
    }
    public class Service : ITest
    {
        public string Echo(string text)
        {
            return text;
        }
        public int Add(int x, int y)
        {
            return x + y;
        }
    }
    public class MyInspector : IEndpointBehavior, IDispatchMessageInspector
    {
        string[] operationNames;

        public MyInspector(params string[] operationNames)
        {
            this.operationNames = operationNames ?? new string[0];
        }

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

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

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

        public void Validate(ServiceEndpoint endpoint)
        {
        }

        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            // by default, action == <serviceContractNamespace>/<serviceContractName>/<operationName>
            string operationName = request.Headers.Action.Substring(request.Headers.Action.LastIndexOf('/') + 1);
            if (this.operationNames.Contains(operationName))
            {
                Console.WriteLine("Inspecting request to operation {0}", operationName);
                Console.WriteLine(request);
                Console.WriteLine();
                return operationName;
            }
            else
            {
                return null;
            }
        }

        public void BeforeSendReply(ref Message reply, object correlationState)
        {
            string operationName = correlationState as string;
            if (operationName != null)
            {
                Console.WriteLine("Inspecting reply from operation {0}", operationName);
                Console.WriteLine(reply);
                Console.WriteLine();
            }
        }
    }
    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        MyInspector inspector = new MyInspector("Add"); // inspecting Add, not Echo
        host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "").Behaviors.Add(inspector);
        host.Open();
        Console.WriteLine("Host opened");

        ChannelFactory<ITest> factory = new ChannelFactory<ITest>(new BasicHttpBinding(), new EndpointAddress(baseAddress));
        ITest proxy = factory.CreateChannel();

        Console.WriteLine("Calling Echo");
        Console.WriteLine(proxy.Echo("Hello world"));
        Console.WriteLine();

        Console.WriteLine("Calling Add");
        Console.WriteLine(proxy.Add(4, 5));

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

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}
公共类StackOverflow_7502134
{
[服务合同]
公共接口测试
{
[经营合同]
字符串回显(字符串文本);
[经营合同]
整数加(整数x,整数y);
}
公共类服务:ITest
{
公共字符串回显(字符串文本)
{
返回文本;
}
公共整数相加(整数x,整数y)
{
返回x+y;
}
}
公共类MyInspector:IEndpointBehavior,IDispatchMessageInspector
{
字符串[]操作名;
公共MyInspector(参数字符串[]操作名称)
{
this.operationNames=operationNames??新字符串[0];
}
public void AddBindingParameters(ServiceEndpoint端点、BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint端点、ClientRuntime ClientRuntime)
{
}
公共无效ApplyDispatchBehavior(ServiceEndpoint端点、EndpointDispatcher端点Dispatcher)
{
endpointDispatcher.DispatcheRuntime.MessageInspectors.Add(此);
}
公共void验证(ServiceEndpoint)
{
}
接收请求后的公共对象(ref消息请求、IClientChannel通道、InstanceContext InstanceContext)
{
//默认情况下,操作==//
string operationName=request.Headers.Action.Substring(request.Headers.Action.LastIndexOf('/')+1);
if(this.operationNames.Contains(operationName))
{
WriteLine(“检查对操作{0}的请求”,operationName);
控制台写入线(请求);
Console.WriteLine();
返回操作名;
}
其他的
{
返回null;
}
}
SendReply之前的公共无效(参考消息回复,对象关联状态)
{
字符串操作名称=作为字符串的correlationState;
if(operationName!=null)
{
WriteLine(“检查来自操作{0}的回复”,操作名);
控制台。写线(回复);
Console.WriteLine();
}
}
}
公共静态无效测试()
{
string baseAddress=“http://“+Environment.MachineName+”:8000/服务”;
ServiceHost主机=新ServiceHost(类型(服务),新Uri(基地址));
MyInspector inspector=新建MyInspector(“添加”);//检查添加,而不是回显
host.AddServiceEndpoint(typeof(ITest),new BasicHttpBinding(),“”)。Behaviors.Add(inspector);
host.Open();
Console.WriteLine(“主机已打开”);
ChannelFactory工厂=新的ChannelFactory(新的BasicHttpBinding(),新的EndpointAddress(baseAddress));
ITest proxy=factory.CreateChannel();
控制台写入线(“呼叫回音”);
Console.WriteLine(proxy.Echo(“helloworld”);
Console.WriteLine();
Console.WriteLine(“调用添加”);
Console.WriteLine(proxy.Add(4,5));
((IClientChannel)代理).Close();
工厂关闭();
控制台。写入(“按ENTER键关闭主机”);
Console.ReadLine();
host.Close();
}
}