문제

내가 노력하고 문제를 촬영하는 웹 서비스 클라이언트에서는 현재 프로젝트입니다.나는 확실하지 않는 플랫폼의 서비스 서버(대부분 램프).고 있다고 생각하는 잘못이 자신의 측면에 울타리로 나 제거하고 잠재적인 문제를 함께 나의 클라이언트입니다.클라이언트는 표준 ASMX 유형 웹 참조 프록시 자동 생성되는 서비스에서 WSDL.

내가 무엇을 얻을 필요가가 원 SOAP 메시지(요청과 응답)

무엇이 가장 좋은 방법에 대해 이?

도움이 되었습니까?

해결책

나는 다음에 변경을했다 web.config 비누 (요청/응답) 봉투를 얻으려면. 이것은 모든 원시 비누 정보를 파일에 출력합니다. trace.log.

<system.diagnostics>
  <trace autoflush="true"/>
  <sources>
    <source name="System.Net" maxdatasize="1024">
      <listeners>
        <add name="TraceFile"/>
      </listeners>
    </source>
    <source name="System.Net.Sockets" maxdatasize="1024">
      <listeners>
        <add name="TraceFile"/>
      </listeners>
    </source>
  </sources>
  <sharedListeners>
    <add name="TraceFile" type="System.Diagnostics.TextWriterTraceListener"
      initializeData="trace.log"/>
  </sharedListeners>
  <switches>
    <add name="System.Net" value="Verbose"/>
    <add name="System.Net.Sockets" value="Verbose"/>
  </switches>
</system.diagnostics>

다른 팁

전체 요청과 로그 파일에 대한 응답을 기록하는 SoApeLextension을 구현할 수 있습니다. 그런 다음 Web.Config에서 SoApeLextension을 활성화하여 디버깅 목적으로 쉽게 켜거나 끄기 쉽습니다. 다음은 제가 사용하기 위해 찾아서 수정 한 예입니다. 제 경우에는 로깅이 log4net에 의해 수행되었지만 로그 메소드를 자신의 것으로 바꿀 수 있습니다.

public class SoapLoggerExtension : SoapExtension
{
    private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
    private Stream oldStream;
    private Stream newStream;

    public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
    {
        return null;
    }

    public override object GetInitializer(Type serviceType)
    {
        return null;
    }

    public override void Initialize(object initializer)
    {

    }

    public override System.IO.Stream ChainStream(System.IO.Stream stream)
    {
        oldStream = stream;
        newStream = new MemoryStream();
        return newStream;
    }

    public override void ProcessMessage(SoapMessage message)
    {

        switch (message.Stage)
        {
            case SoapMessageStage.BeforeSerialize:
                break;
            case SoapMessageStage.AfterSerialize:
                Log(message, "AfterSerialize");
                    CopyStream(newStream, oldStream);
                    newStream.Position = 0;
                break;
                case SoapMessageStage.BeforeDeserialize:
                    CopyStream(oldStream, newStream);
                    Log(message, "BeforeDeserialize");
                break;
            case SoapMessageStage.AfterDeserialize:
                break;
        }
    }

    public void Log(SoapMessage message, string stage)
    {

        newStream.Position = 0;
        string contents = (message is SoapServerMessage) ? "SoapRequest " : "SoapResponse ";
        contents += stage + ";";

        StreamReader reader = new StreamReader(newStream);

        contents += reader.ReadToEnd();

        newStream.Position = 0;

        log.Debug(contents);
    }

    void ReturnStream()
    {
        CopyAndReverse(newStream, oldStream);
    }

    void ReceiveStream()
    {
        CopyAndReverse(newStream, oldStream);
    }

    public void ReverseIncomingStream()
    {
        ReverseStream(newStream);
    }

    public void ReverseOutgoingStream()
    {
        ReverseStream(newStream);
    }

    public void ReverseStream(Stream stream)
    {
        TextReader tr = new StreamReader(stream);
        string str = tr.ReadToEnd();
        char[] data = str.ToCharArray();
        Array.Reverse(data);
        string strReversed = new string(data);

        TextWriter tw = new StreamWriter(stream);
        stream.Position = 0;
        tw.Write(strReversed);
        tw.Flush();
    }
    void CopyAndReverse(Stream from, Stream to)
    {
        TextReader tr = new StreamReader(from);
        TextWriter tw = new StreamWriter(to);

        string str = tr.ReadToEnd();
        char[] data = str.ToCharArray();
        Array.Reverse(data);
        string strReversed = new string(data);
        tw.Write(strReversed);
        tw.Flush();
    }

    private void CopyStream(Stream fromStream, Stream toStream)
    {
        try
        {
            StreamReader sr = new StreamReader(fromStream);
            StreamWriter sw = new StreamWriter(toStream);
            sw.WriteLine(sr.ReadToEnd());
            sw.Flush();
        }
        catch (Exception ex)
        {
            string message = String.Format("CopyStream failed because: {0}", ex.Message);
            log.Error(message, ex);
        }
    }
}

[AttributeUsage(AttributeTargets.Method)]
public class SoapLoggerExtensionAttribute : SoapExtensionAttribute
{
    private int priority = 1; 

    public override int Priority
    {
        get { return priority; }
        set { priority = value; }
    }

    public override System.Type ExtensionType
    {
        get { return typeof (SoapLoggerExtension); }
    }
}

그런 다음 yournamespace와 yourASSEMBLY가 SoApeLextension의 클래스 및 어셈블리를 가리키는 Web.config에 다음 섹션을 추가합니다.

<webServices>
  <soapExtensionTypes>
    <add type="YourNamespace.SoapLoggerExtension, YourAssembly" 
       priority="1" group="0" />
  </soapExtensionTypes>
</webServices>

Web.config 또는 Serializer 클래스의 모든 소란이 확실하지 않습니다. 아래 코드는 나에게 효과가있었습니다.

XmlSerializer xmlSerializer = new XmlSerializer(myEnvelope.GetType());

using (StringWriter textWriter = new StringWriter())
{
    xmlSerializer.Serialize(textWriter, myEnvelope);
    return textWriter.ToString();
}

노력하다 fiddler2 요청과 응답을 검사 할 수 있습니다. 피들러는 HTTP 및 HTTPS 트래픽과 함께 작동한다는 점에 주목할 가치가 있습니다.

그것은 다음과 같 팀 카터의 솔루션을 작동하지 않을 경우 호출하여 웹 참고 예외가 발생합니다.내가 하려고 했는데에서 얻을 원 웹 resonse 할 수 있도록 검사(코드)에 오류가 핸들러면 예외가 발생합니다.그러나 내가 찾는다는 응답을 로그에 의해 작성된 팀의 방법은 빈면 예외가 발생합니다.나는 완전히 이해하지 못하는 코드,하지만 그것이 나타나는 팀의 방법으로 인하는 프로세스 포인트다.순이가 이미을 무효화하고 폐기 웹 응답입니다.

나는 작업을 하는 클라이언트의 개발 수동으로 웹 서비스 수준이 낮은 코딩이다.이 시점에서,그들은 그들 자신의 내부 프로세스는 오류 메시지로 HTML 형식의 메시지를하기 전에 응답을 비누 형식의 응답.물론,자료.Net 웹 참고 불니다.을 얻을 수 있다면에서 원하는 HTTP 응답한 후에 예외가 발생,내가 볼 수 있었다고 분석이 어떤 비누 내에 응답 혼합 반환된 HTTP 응답고 알고 있는 그들은 내 데이터를 확인하거나지 않습니다.

나중에...

여기에는 솔루션을 작동하지 않은 후에도 execption(참고 난 후에만 응답을 얻을 수 있는 요청을 너무):

namespace ChuckBevitt
{
    class GetRawResponseSoapExtension : SoapExtension
    {
        //must override these three methods
        public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
        {
            return null;
        }
        public override object GetInitializer(Type serviceType)
        {
            return null;
        }
        public override void Initialize(object initializer)
        {
        }

        private bool IsResponse = false;

        public override void ProcessMessage(SoapMessage message)
        {
            //Note that ProcessMessage gets called AFTER ChainStream.
            //That's why I'm looking for AfterSerialize, rather than BeforeDeserialize
            if (message.Stage == SoapMessageStage.AfterSerialize)
                IsResponse = true;
            else
                IsResponse = false;
        }

        public override Stream ChainStream(Stream stream)
        {
            if (IsResponse)
            {
                StreamReader sr = new StreamReader(stream);
                string response = sr.ReadToEnd();
                sr.Close();
                sr.Dispose();

                File.WriteAllText(@"C:\test.txt", response);

                byte[] ResponseBytes = Encoding.ASCII.GetBytes(response);
                MemoryStream ms = new MemoryStream(ResponseBytes);
                return ms;

            }
            else
                return stream;
        }
    }
}

여기에의 구성 방법은 config file:

<configuration>
     ...
  <system.web>
    <webServices>
      <soapExtensionTypes>
        <add type="ChuckBevitt.GetRawResponseSoapExtension, TestCallWebService"
           priority="1" group="0" />
      </soapExtensionTypes>
    </webServices>
  </system.web>
</configuration>

"TestCallWebService"갈까요로 대체될 라이브러리의 이름(일어난 이름의 테스트는 콘솔 응용 프로그램에서 작업).

당신이 정말로 이동 ChainStream;당신이 할 수 있어야 이상에서 단순히다면:

public override void ProcessMessage(SoapMessage message)
{
    if (message.Stage == SoapMessageStage.BeforeDeserialize)
    {
        StreamReader sr = new StreamReader(message.Stream);
        File.WriteAllText(@"C:\test.txt", sr.ReadToEnd());
        message.Stream.Position = 0; //Will blow up 'cause type of stream ("ConnectStream") doesn't alow seek so can't reset position
    }
}

당신이 볼 SoapMessage.스트림,그것을 읽기만 사용할 수 있는 스트림 데이터를 검사에 이점이다.이사인 당신이 읽고 스트림을,이후의 처리에 폭탄이 없는 데이터 오류를 발견하(스트림에서 끝)과할 수 없습니다 다시 설정치를 시작했다.

흥미롭게도,당신이 할 경우 두 방법 모두에 ChainStream 고다는 방법으로,다 방법이기 때문에 일을 변경할 스트림에서 유형 ConnectStream 을 MemoryStream 에 ChainStream 및 MemoryStream 허용하지 않 찾는 작업입니다.(나 캐스팅 ConnectStream 을 MemoryStream-지 않을 수 있습니다.)

그래서.....Microsoft 해를 하도록 허용하거나 추구에서 작업 ChainStream 유형 또는 SoapMessage.스트림을 진정으로 읽기 전용 사본을 그대로 사용할 수 있습니다!(쓰기 하원 의원은,등등...)

하나 추가점이다.후을 만드는 방법은 적을 원하는 HTTP 응답 후에는 예외,내가 여전히 못해 전체 응답(에 의해 결정되는 HTTP 탐).이었기 때문에 개발한 웹 서비스에 추가 HTML 오류 메시지를 시작 부분의 응답,되지 않았을 조정 Content-Length 헤더는,그래서 Content-Length 값보다 적은 크기의 실제 응답체.에있는 모든 콘텐츠 길이 값을 문자 수는-나머지 실종되었다.분명히 할 때이다.Net 을 읽고 스트림 응답,단지 그것을 읽고 Content-Length 문자 수를 허용하지 않는 콘텐츠에 대해 길이의 값 possibily 는 잘못입니다.이것은 그것이 있어야로;하지만하면 Content-Length 헤더값이 잘못된 유일한 방법은 당신이 이제까지 전체 응답은 HTTP 스니퍼(나는 사용자 HTTP 에서 분석기 http://www.ieinspector.com).

나는 기본 스트림의 프레임 워크 프로세스로 로깅 스트림을 연결하여 프레임 워크가 로깅을하는 것을 선호합니다. 체인 스트림 방법에서 요청과 응답을 결정할 수 없기 때문에 다음은 내가 원하는만큼 깨끗하지 않습니다. 다음은 내가 처리하는 방법입니다. 스트림 아이디어를 무시한 Jon Hanna에게 감사드립니다.

public class LoggerSoapExtension : SoapExtension
{
    private static readonly string LOG_DIRECTORY = ConfigurationManager.AppSettings["LOG_DIRECTORY"];
    private LogStream _logger;

    public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
    {
        return null;
    }
    public override object GetInitializer(Type serviceType)
    {
        return null;
    }
    public override void Initialize(object initializer)
    {
    }
    public override System.IO.Stream ChainStream(System.IO.Stream stream)
    {
        _logger = new LogStream(stream);
        return _logger;
    }
    public override void ProcessMessage(SoapMessage message)
    {
        if (LOG_DIRECTORY != null)
        {
            switch (message.Stage)
            {
                case SoapMessageStage.BeforeSerialize:
                    _logger.Type = "request";
                    break;
                case SoapMessageStage.AfterSerialize:
                    break;
                case SoapMessageStage.BeforeDeserialize:
                    _logger.Type = "response";
                    break;
                case SoapMessageStage.AfterDeserialize:
                    break;
            }
        }
    }
    internal class LogStream : Stream
    {
        private Stream _source;
        private Stream _log;
        private bool _logSetup;
        private string _type;

        public LogStream(Stream source)
        {
            _source = source;
        }
        internal string Type
        {
            set { _type = value; }
        }
        private Stream Logger
        {
            get
            {
                if (!_logSetup)
                {
                    if (LOG_DIRECTORY != null)
                    {
                        try
                        {
                            DateTime now = DateTime.Now;
                            string folder = LOG_DIRECTORY + now.ToString("yyyyMMdd");
                            string subfolder = folder + "\\" + now.ToString("HH");
                            string client = System.Web.HttpContext.Current != null && System.Web.HttpContext.Current.Request != null && System.Web.HttpContext.Current.Request.UserHostAddress != null ? System.Web.HttpContext.Current.Request.UserHostAddress : string.Empty;
                            string ticks = now.ToString("yyyyMMdd'T'HHmmss.fffffff");
                            if (!Directory.Exists(folder))
                                Directory.CreateDirectory(folder);
                            if (!Directory.Exists(subfolder))
                                Directory.CreateDirectory(subfolder);
                            _log = new FileStream(new System.Text.StringBuilder(subfolder).Append('\\').Append(client).Append('_').Append(ticks).Append('_').Append(_type).Append(".xml").ToString(), FileMode.Create);
                        }
                        catch
                        {
                            _log = null;
                        }
                    }
                    _logSetup = true;
                }
                return _log;
            }
        }
        public override bool CanRead
        {
            get
            {
                return _source.CanRead;
            }
        }
        public override bool CanSeek
        {
            get
            {
                return _source.CanSeek;
            }
        }

        public override bool CanWrite
        {
            get
            {
                return _source.CanWrite;
            }
        }

        public override long Length
        {
            get
            {
                return _source.Length;
            }
        }

        public override long Position
        {
            get
            {
                return _source.Position;
            }
            set
            {
                _source.Position = value;
            }
        }

        public override void Flush()
        {
            _source.Flush();
            if (Logger != null)
                Logger.Flush();
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            return _source.Seek(offset, origin);
        }

        public override void SetLength(long value)
        {
            _source.SetLength(value);
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            count = _source.Read(buffer, offset, count);
            if (Logger != null)
                Logger.Write(buffer, offset, count);
            return count;
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            _source.Write(buffer, offset, count);
            if (Logger != null)
                Logger.Write(buffer, offset, count);
        }
        public override int ReadByte()
        {
            int ret = _source.ReadByte();
            if (ret != -1 && Logger != null)
                Logger.WriteByte((byte)ret);
            return ret;
        }
        public override void Close()
        {
            _source.Close();
            if (Logger != null)
                Logger.Close();
            base.Close();
        }
        public override int ReadTimeout
        {
            get { return _source.ReadTimeout; }
            set { _source.ReadTimeout = value; }
        }
        public override int WriteTimeout
        {
            get { return _source.WriteTimeout; }
            set { _source.WriteTimeout = value; }
        }
    }
}
[AttributeUsage(AttributeTargets.Method)]
public class LoggerSoapExtensionAttribute : SoapExtensionAttribute
{
    private int priority = 1;
    public override int Priority
    {
        get
        {
            return priority;
        }
        set
        {
            priority = value;
        }
    }
    public override System.Type ExtensionType
    {
        get
        {
            return typeof(LoggerSoapExtension);
        }
    }
}

사용중인 언어를 지정하지 않았지만 사용할 수있는 C# / .NET를 가정했습니다. 비누 확장.

그렇지 않으면, 스나이퍼를 사용하십시오 Wireshark

는 것을 깨달았어요 매우는 자,그리고 그 이후 언어지 않은 실제로 지정하기 VB.NET 솔루션 기반으로 Bimmerbound 의 대답은 경우에는 사람이 일어나는 우연히 발견이 필요한 솔루션입니다.참고:당신이해야에 대한 참조가 있 이 클래스에서는 프로젝트에서 당신은하지 않는다.

 Shared Function returnSerializedXML(ByVal obj As Object) As String
    Dim xmlSerializer As New System.Xml.Serialization.XmlSerializer(obj.GetType())
    Dim xmlSb As New StringBuilder
    Using textWriter As New IO.StringWriter(xmlSb)
        xmlSerializer.Serialize(textWriter, obj)
    End Using


    returnSerializedXML = xmlSb.ToString().Replace(vbCrLf, "")

End Function

단순히 함수를 호출하고 그것이 문자열을 반환으로 직렬화된 xml 의 개체 당신을 전달하려고 하는 웹 서비스(현실적으로 이해야 하는 작업에 대한 모든 개체가 당신이 그것을 던져도).

주석으로,대화 기능을 반환하기 전에 xml 은 지구 밖으로 vbCrLf 에서 문자를 출력합니다.요한 것은 그들의 무리에서 생성된 xml 그러나 이것은 분명히 따라 달라집하는 직렬화하여,그리고 나는 생각할 수 있을 제거하는 동안 개체로 전송되는 웹 서비스입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top