2014-02-13 2 views
2

제 솔루션에는 세 가지 프로젝트가 있습니다. 하나는 WCF 서비스이고, 다른 하나는 웹 서비스를 호출하는 Winforms 응용 프로그램이고, 마지막은 클래스가 비누 확장 클래스를 확장하는 디자인을 가진 클래스 라이브러리입니다.WCF 서비스 끝에서 들어오고 나가는 XML을 어떻게 캡쳐합니까?

내 목표는 내 Winforms 응용 프로그램에서 WCF 서비스를 호출 할 때 응답 & 요청 xml을 캡처하는 것입니다. XML을 캡처하려고 할 때 개체 참조가 설정되지 않은 오류가 발생합니다.

다음은 클래스 라이브러리 소스 코드입니다.

private void button1_Click(object sender, EventArgs e) 
{ 

    using (ServiceRef.TestServiceSoapClient oService = new ServiceRef.TestServiceSoapClient()) 
    { 
     textBox1.Text = oService.HelloWorld("Sudip"); 
     var soapRequest = SoapLogger.TraceExtension.XmlRequest.InnerXml; 
     var soapResponse = SoapLogger.TraceExtension.XmlResponse.InnerXml; 
    } 
} 

이 두 라인

이 가

난 그냥 알아낼 수없는 객체 참조 오류

var soapRequest = SoapLogger.TraceExtension.XmlRequest.InnerXml; 
var soapResponse = SoapLogger.TraceExtension.XmlResponse.InnerXml; 
를 일으키는 : 내 윈폼 응용 프로그램에서 웹 서비스를 호출 오전 방법은 다음과

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Web.Services; 
using System.Web.Services.Protocols; 
using System.IO; 
using System.Net; 
using System.Xml; 

namespace SoapLogger 
{ 
public class TraceExtension : SoapExtension 
{ 
    private Stream oldStream; 
    private Stream newStream; 

    private static XmlDocument xmlRequest; 
    /// <summary> 
    /// Gets the outgoing XML request sent to PayPal 
    /// </summary> 
    public static XmlDocument XmlRequest 
    { 
     get { return xmlRequest; } 
    } 

    private static XmlDocument xmlResponse; 
    /// <summary> 
    /// Gets the incoming XML response sent from PayPal 
    /// </summary> 
    public static XmlDocument XmlResponse 
    { 
     get { return xmlResponse; } 
    } 

    /// <summary> 
    /// Save the Stream representing the SOAP request 
    /// or SOAP response into a local memory buffer. 
    /// </summary> 
    /// <param name="stream"> 
    /// <returns></returns> 
    public override Stream ChainStream(Stream stream) 
    { 
     oldStream = stream; 
     newStream = new MemoryStream(); 
     return newStream; 
    } 

    /// <summary> 
    /// If the SoapMessageStage is such that the SoapRequest or 
    /// SoapResponse is still in the SOAP format to be sent or received, 
    /// save it to the xmlRequest or xmlResponse property. 
    /// </summary> 
    /// <param name="message"> 
    public override void ProcessMessage(SoapMessage message) 
    { 
     switch (message.Stage) 
     { 
      case SoapMessageStage.BeforeSerialize: 
       break; 
      case SoapMessageStage.AfterSerialize: 
       xmlRequest = GetSoapEnvelope(newStream); 
       CopyStream(newStream, oldStream); 
       break; 
      case SoapMessageStage.BeforeDeserialize: 
       CopyStream(oldStream, newStream); 
       xmlResponse = GetSoapEnvelope(newStream); 
       break; 
      case SoapMessageStage.AfterDeserialize: 
       break; 
     } 
    } 

    /// <summary> 
    /// Returns the XML representation of the Soap Envelope in the supplied stream. 
    /// Resets the position of stream to zero. 
    /// </summary> 
    /// <param name="stream"> 
    /// <returns></returns> 
    private XmlDocument GetSoapEnvelope(Stream stream) 
    { 
     XmlDocument xml = new XmlDocument(); 
     stream.Position = 0; 
     StreamReader reader = new StreamReader(stream); 
     xml.LoadXml(reader.ReadToEnd()); 
     stream.Position = 0; 
     return xml; 
    } 

    /// <summary> 
    /// Copies a stream. 
    /// </summary> 
    /// <param name="from"> 
    /// <param name="to"> 
    private void CopyStream(Stream from, Stream to) 
    { 
     TextReader reader = new StreamReader(from); 
     TextWriter writer = new StreamWriter(to); 
     writer.WriteLine(reader.ReadToEnd()); 
     writer.Flush(); 
    } 
    #region NoOp 
    /// <summary> 
    /// Included only because it must be implemented. 
    /// </summary> 
    /// <param name="methodInfo"> 
    /// <param name="attribute"> 
    /// <returns></returns> 
    public override object GetInitializer(LogicalMethodInfo methodInfo, 
     SoapExtensionAttribute attribute) 
    { 
     return null; 
    } 

    /// <summary> 
    /// Included only because it must be implemented. 
    /// </summary> 
    /// <param name="WebServiceType"> 
    /// <returns></returns> 
    public override object GetInitializer(Type WebServiceType) 
    { 
     return null; 
    } 

    /// <summary> 
    /// Included only because it must be implemented. 
    /// </summary> 
    /// <param name="initializer"> 
    public override void Initialize(object initializer) 
    { 
    } 
    #endregion NoOp 
} 

입니다 왜 내가 오류가 발생하는지.

Winforms 응용 프로그램에는 xml을 캡처하기 위해 클래스 라이브러리 어셈블리를 등록하는 app.config이 있습니다. 여기 내 app.config 자세한

<?xml version="1.0"?> 
<configuration> 
<system.serviceModel> 
<bindings> 
<basicHttpBinding> 
<binding name="TestServiceSoap"/> </basicHttpBinding> 
</bindings> <client> <endpoint address="http://localhost:6804/Service1.asmx" 
binding="basicHttpBinding" bindingConfiguration="TestServiceSoap" 
contract="ServiceRef.TestServiceSoap" name="TestServiceSoap"/> 
</client> 
</system.serviceModel> 
<system.web> 
<compilation debug="true" targetFramework="4.0" /> 
<webServices> <soapExtensionTypes> 
<add type="SoapLogger.TraceExtension,SoapLogger" priority="1" group="0" /> 
</soapExtensionTypes> </webServices> 
</system.web> 
<startup> 
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> 
</startup> </configuration> 

내가 구글 그냥 다음 요청/응답 XML을 캡처 나는 많은 문서의이 종류를 가지고하는 방법을 알고 검색

입니다. 나는 많은 것을 따라 갔지만 아무것도 작동하지 않는다.

난 다음에이 URL은 작업이 내가 명확하지 않다 만드는 중이라서 실수 어떤 종류의

http://jramirezdev.net/blog/c-tip-capturar-los-mensajes-soap-de-un-servicio-asmx-que-hemos-referenciado을 수행하세요. 내 클래스 라이브러리 메서드에서 모든 메서드에서 중단 점을 설정했지만 웹 서비스 호출이 메서드가 클래스 라이브러리에서 실행되지 않았을 때. wireshark와 같은 도구를 사용하고 싶지 않습니다. 요청/응답 XML을 캡처하기 위해 피들러를 사용하는 대신 프로그래밍 방식으로 동일한 작업을 수행하려고합니다.

제 실수를 안내해주십시오. 개체 참조가 설정되지 않은 이유는 무엇입니까? 내 코드를 살펴하거나 URL 링크에 가서 내 접근

+0

http://stackoverflow.com/questions/11956204/httpwebrequest-not-sending-useragent –

+0

발견되지 http://jramirezdev.net/blog/c-tip-capturar-los-mensajes-soap- de-un-servicio-asmx-que-hemos-referenceciado – Kiquenet

답변

3

xmlRequest/xmlResponse이 (가) 액세스 할 때 초기화되지 않았기 때문에 오류가 발생했습니다. 따라서 null을 확인하거나 기본 인스턴스를 만들어보십시오. 당신이 도움이

var soapRequest = SoapLogger.TraceExtension.XmlRequest.InnerXml; 
var soapResponse = SoapLogger.TraceExtension.XmlResponse.InnerXml; 

희망을 호출하기 전에

코드에서

그들은 단지 ProcessMessage(SoapMessage message){}에 초기화, 메소드가 호출되어 있는지 확인합니다.

는 편집 :

밀접하게 코드를 검토 후, 나는 당신이 쓴 확장 (SoapExtension가) ASP.NET의 XML 웹 서비스에 대한 것을 깨달았다, 그리고 그것은 WCF 서비스와 어떤 사업을 없었다.

WCF 서비스에서 요청을 검토하고 회신하려면 System.ServiceModel.Dispatcher.IDispatchMessageInspector을 구현하여 서비스 측면에서 발송자를 확장 할 수 있습니다.

는 현재 http://msdn.microsoft.com/en-us/library/ms733104%28v=vs.100%29.aspx

+0

uplzz는이 주제에 대한 적절한 기사를 자세히 리다이렉트 할 수 있습니다. 자세한 내용은 내 PC에서 실행할 수있는 전체 작업 코드 샘플을 얻을 수 있습니다. thanks – Thomas

+0

@ 토마스 내 업데이트 된 답변 –

+0

'System.ServiceModel.Dispatcher.IDispatchMessageInspector'를 사용하여 실제 실제 코드를 확인하십시오. – Kiquenet

3
  1. 구성 WCF Tracing
  2. 보내기에 어떤 문제가 있는지 알려주세요 /를 SvcTraceViewer.exe 로그 뷰어를 가져옵니다 일부 메시지
  3. 를 받고 추적을 엽니 다 산출.
  4. 이익.
12

단순히 우리가 요청 메시지를 추적 할 수있는 예를 찾을 수 있습니다.

OperationContext context = OperationContext.Current; 

if (context != null && context.RequestContext != null) 

{ 

Message msg = context.RequestContext.RequestMessage; 

string reqXML = msg.ToString(); 

} 
+0

WebService ASMX를 사용하는 클라이언트에 유효합니까? – Kiquenet

관련 문제