2013-03-26 1 views
1

WCF 메시지 검사에서 Message 개체의 입력 매개 변수 값을 찾는 방법은 무엇입니까?WCF 메시지 검사에서 Message 개체의 입력 매개 변수 값을 찾는 방법은 무엇입니까?

은 내가 MessageInspector를 사용하여 아래의 클래스가있어 :

public class MyMessageInspector : IDispatchMessageInspector 
{ 
    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) 
    { 
     // TODO: how to find the value of the siteName parameter if exists? 

     Console.WriteLine("Incoming request: {0}", request); 
     return null; 
    } 

    public void BeforeSendReply(ref Message reply, object correlationState) 
    { 

    } 
} 

가 어떻게 내의 WebMethod의 사이트 이름 입력 매개 변수의 값을 추출 할 수 있을까? 모든 webmethod에는 siteName 입력 매개 변수가 있습니다.

답변

2

당신은 Message를 역 직렬화하고 필드를 사용하지만, 메시지와 매개 변수 사이의 변환이 메시지 포맷터에 의해 이루어집니다

+0

덕분에, 나는 IParameterInspector을 사용하고 싶어하지만 IParameterInspector를 사용하여 사이트 이름 인 매개 변수를 찾을 수 없습니다, 그래서 그것은 입력 매개 변수 이름 만 값이 없습니다. –

+0

반사 - 문자열 메서드 이름 –

+0

에 의한 매개 변수 이름을 사용하면 메시지에서 Xml XPath보다 더 효율적입니까? –

7

더 나은 IParameterInspector을 사용하는 것입니다 수 있습니다. 그렇게 할 수는 있지만 매개 변수의 값을 얻기 위해 메시지를 읽은 후에는 메시지가 으로 사용되었으므로 메시지를 WCF로 전달하기 전에 다시 작성해야합니다 (메시지 검사기에서 요청 참조로 전달되므로 실제로 소비해야하는 경우이를 대체 할 수 있습니다).

@burning_LEGION에서 언급했듯이 매개 변수 관리자는 시나리오에 가장 적합한 옵션입니다. Inspector 자체에는 매개 변수 이름이 없지만 매개 변수 관리자를 추가하는 데 사용할 동작 설명에서 가져올 수 있습니다. 아래 코드는 어떻게 수행 할 수 있는지 보여줍니다.

public class StackOverflow_15637994 
{ 
    [ServiceContract] 
    public interface ITest 
    { 
     [OperationContract] 
     string Echo(string text); 
     [OperationContract] 
     int Execute(string op, int x, int y); 
     [OperationContract] 
     bool InOutAndRefParameters(int x, ref int y, out int z); 
    } 
    public class Service : ITest 
    { 
     public string Echo(string text) 
     { 
      return text; 
     } 

     public int Execute(string op, int x, int y) 
     { 
      return x + y; 
     } 

     public bool InOutAndRefParameters(int x, ref int y, out int z) 
     { 
      z = y; 
      y = x; 
      return true; 
     } 
    } 
    public class MyInspector : IParameterInspector 
    { 
     string[] inputParameterNames; 
     string[] outputParameterNames; 
     public MyInspector(string[] inputParameterNames, string[] outputParameterNames) 
     { 
      this.inputParameterNames = inputParameterNames; 
      this.outputParameterNames = outputParameterNames; 
     } 

     public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState) 
     { 
      Console.WriteLine("Operation: {0}", operationName); 
      Console.WriteLine(" Result: {0}", returnValue); 
      for (int i = 0; i < outputs.Length; i++) 
      { 
       Console.WriteLine(" [out] {0}: {1}", this.outputParameterNames[i], outputs[i]); 
      } 
     } 

     public object BeforeCall(string operationName, object[] inputs) 
     { 
      Console.WriteLine("Operation: {0}", operationName); 
      for (int i = 0; i < inputs.Length; i++) 
      { 
       Console.WriteLine(" {0}: {1}", this.inputParameterNames[i], inputs[i]); 
      } 

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

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

     public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) 
     { 
      foreach (var operation in endpoint.Contract.Operations) 
      { 
       string[] inputParamNames = operation.Messages[0].Body.Parts 
        .OrderBy(mpd => mpd.Index) 
        .Select(mpd => mpd.Name) 
        .ToArray(); 
       string[] outputParamNames = null; 
       if (operation.Messages.Count > 1) 
       { 
        outputParamNames = operation.Messages[1].Body.Parts 
         .OrderBy(mpd => mpd.Index) 
         .Select(mpd => mpd.Name) 
         .ToArray(); 
       } 

       MyInspector inspector = new MyInspector(inputParamNames, outputParamNames); 
       endpointDispatcher.DispatchRuntime.Operations[operation.Name].ParameterInspectors.Add(inspector); 
      } 
     } 

     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)); 
     ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), ""); 
     endpoint.Behaviors.Add(new MyBehavior()); 
     host.Open(); 
     Console.WriteLine("Host opened"); 

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

     proxy.Echo("Hello"); 
     proxy.Execute("foo", 2, 5); 
     int z; 
     int y = 2; 
     proxy.InOutAndRefParameters(3, ref y, out z); 

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

     Console.Write("Press ENTER to close the host"); 
     Console.ReadLine(); 
     host.Close(); 
    } 
}