2
如何強制IMessageInspector
僅在調用特定操作時觸發,而不是在每次調用服務時觸發?目前,我正在將一個自定義的IEndpointBehavior
應用到稱爲此IMessageInspector
的端點,但這不完全是我想要做的...爲單個操作啓用SOAP消息檢查
如何強制IMessageInspector
僅在調用特定操作時觸發,而不是在每次調用服務時觸發?目前,我正在將一個自定義的IEndpointBehavior
應用到稱爲此IMessageInspector
的端點,但這不完全是我想要做的...爲單個操作啓用SOAP消息檢查
消息檢查器綁定到調度運行時對象,它是單個爲每個端點,而不是操作。如果參數檢查器有效,那麼您可以使用它(它綁定到操作),但是如果您需要消息檢查器,那麼它不能綁定到單個操作。但是,您可以在檢查器內部檢查操作是否符合您的期望(基於操作標題,每個操作都是唯一的),如下面的代碼所示。
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();
}
}