Получение данных в формате RAW Soap от клиента веб-справочника, работающего в ASP.net

Я пытаюсь решить проблему с клиентом веб-службы в моем текущем проекте. Я не уверен в платформе Service Server (скорее всего, LAMP). Я считаю, что на их стороне забора есть ошибка, поскольку я устранил потенциальные проблемы с моим клиентом. Клиент представляет собой стандартный прокси-сервер веб-ссылок типа ASMX, автоматически сгенерированный из WSDL службы.

Мне нужно получить сообщения RAW SOAP (запросы и ответы)

Как лучше всего это сделать?


person Andrew Harry    schedule 19.11.2008    source источник


Ответы (9)


Я внес следующие изменения в web.config, чтобы получить конверт SOAP (запрос / ответ). Это выведет всю необработанную информацию SOAP в файл 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>
person Community    schedule 09.01.2009
comment
Я считаю, что это наиболее эффективный метод доступа к необработанным данным xml. - person Andrew Harry; 10.03.2009
comment
Это не работает для меня в 02/2012 с использованием VS 2010. Кто-нибудь знает более современное решение? - person qxotk; 29.02.2012
comment
работает! но знаете ли вы, как отображать расшифрованные ответные сообщения, если используется HTTPS? - person Felipe Sabino; 21.08.2012
comment
Это полезно. Однако в моем случае ответы заархивированы, и извлечение ASCII или шестнадцатеричных кодов из объединенного вывода - это боль. Являются ли их альтернативные методы вывода двоичными или только текстовыми? - person ; 15.01.2013
comment
Я добавил это в файл web.config, но не могу найти файл журнала. Я совсем не знаком с ASP, поэтому я не уверен, куда поместить этот отредактированный файл web.config и где найти журнал. Пожалуйста, помогите кому-нибудь - person Dediqated; 04.04.2013
comment
@Dediqated - вы можете указать путь к файлу trace.log, изменив значение атрибута initializeData в примере выше. - person DougCouto; 24.05.2013
comment
Это больше бесполезно, я использовал wirehark для просмотра необработанных данных SOAP. Но все равно спасибо! - person Dediqated; 24.05.2013
comment
работает на IIS 7.5. Я предлагаю изменить путь к файлу журнала трассировки, например c: \ temp \ trace.log, чтобы вы знали, где он находится! - person Stanley; 18.04.2014
comment
в какой папке будет генерироваться trace.log? - person Thomas; 18.10.2014
comment
@Thomas находится в корне папки вашего проекта - person ejhost; 06.02.2015
comment
Хорошо. Но XML для меня выглядит так: System.Net Verbose: 0: [14088] 00000000: 3C 3F 78 6D 6C 20 76 65-72 73 69 6F 6E 3D 22 31: ‹? Xml version = 1 System.Net Verbose: 0 : [14088] 00000010: 2E 30 22 20 65 6E 63 6F-64 69 6E 67 3D 22 75 74: .0 encoding = ut ....... Есть идеи, как отформатировать его или иметь только данные xml.? - person Habeeb; 05.11.2015
comment
Это также работает в app.config, я получаю сообщение, что поле maxdatasize не разрешено, но оно все еще работает! - person Cerveser; 17.12.2015
comment
Могу я использовать это для просмотра httpheader? - person ; 20.12.2016
comment
Чтобы удалить шестнадцатеричные данные, используйте tracemode = protocolonly. Я также установил maxdatasize = 9999. Я получаю предупреждения для обоих этих атрибутов, но они работают. - person Collin Anderson; 31.03.2017
comment
Спасибо, @CollinAnderson, добавление протокола только не позволяет трассировщику фрагментировать данные ответа, а maxsize не дает их обрезать. Я бы также добавил, что если вы измените расширение на .svclog, вы можете открыть журнал в Microsoft Service Trace Viewer по умолчанию, что значительно упростит интерпретацию трассировок. - person WarrenB; 20.06.2017

Вы можете реализовать SoapExtension, который записывает полный запрос и ответ в файл журнала. Затем вы можете включить SoapExtension в web.config, что упрощает включение / выключение в целях отладки. Вот пример, который я нашел и изменил для себя. В моем случае ведение журнала было выполнено с помощью 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); }
    }
}

Затем вы добавляете следующий раздел в свой web.config, где YourNamespace и YourAssembly указывают на класс и сборку вашего SoapExtension:

<webServices>
  <soapExtensionTypes>
    <add type="YourNamespace.SoapLoggerExtension, YourAssembly" 
       priority="1" group="0" />
  </soapExtensionTypes>
</webServices>
person John Lemp    schedule 19.11.2008
comment
Я попробую. Я искал расширения для мыла, но мне показалось, что это больше для хостинга службы. Поставлю галочку, если заработает :) - person Andrew Harry; 20.11.2008
comment
Да, это будет работать для регистрации вызовов, сделанных из вашего веб-приложения через сгенерированный прокси. - person John Lemp; 20.11.2008
comment
Я пошел по этому пути, он работает очень хорошо, и я могу использовать xpath, чтобы замаскировать любые конфиденциальные данные перед их регистрацией. - person Dave Baghdanov; 05.06.2014
comment
Мне нужно было добавить заголовки в запрос мыла на клиенте. Это мне помогло. рифмы. ru / 2015/04/29 / - person Rhyous; 30.04.2015
comment
Я также новичок в С # и не уверен, что указать для имени сборки. Расширение не запускается. - person Collin Anderson; 31.03.2017
comment
Применимо к WCF Services (svc) или только Web Services (asmx)? - person Kiquenet; 25.06.2018

Не уверен, к чему такая возня с web.config или классом сериализатора. Приведенный ниже код работал у меня:

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

using (StringWriter textWriter = new StringWriter())
{
    xmlSerializer.Serialize(textWriter, myEnvelope);
    return textWriter.ToString();
}
person Bimmerbound    schedule 22.01.2015
comment
Откуда myEnvelope? - person ProfK; 16.03.2015
comment
Я не понимаю, почему этот ответ не получил больше голосов, прямо и по существу! Отличная работа! - person Batista; 06.08.2015
comment
myEnvalope будет объектом, который вы отправляете через веб-службу. Я не мог заставить это работать, как описано (в частности, функция textWriter.tostring), но она работала достаточно хорошо для моих целей в режиме отладки, так как вы можете видеть необработанный xml после вызова сериализации. Очень ценю этот ответ, поскольку некоторые из других работали со смешанными результатами (например, ведение журнала с использованием web.config вернуло только часть xml, и его было не очень легко разобрать). - person user2366842; 09.10.2015
comment
@Bimmerbound: будет ли это работать с защищенными мыльными сообщениями, отправляемыми через зашифрованный VPN? - person Our Man in Bananas; 09.03.2016
comment
myEnvelope - это объект xml, из которого вы пытаетесь получить необработанный XML. - person Bimmerbound; 05.10.2016
comment
Я могу использовать этот код для своего объекта ответа. Однако мне трудно захватить запрос, поскольку мой веб-метод принимает несколько параметров (например, mySoapHttpClientProtocolRequest.Method1 (para1, para2, para3)). Если я передаю mySoapHttpClientProtocolRequest как myEnvelope, первая строка выдает исключение. Произошла ошибка, отражающая тип XXX. Как в этом случае я могу записать SOAP-сообщение запроса? Спасибо! - person AngieM; 22.02.2017
comment
@AngieM в этом случае более полезен ответ в stackoverflow.com/a/428223/6505594 (вы должны использовать код в этом ответе для сериализации para1, para2 и para3, а не самого soapHttpClientProtocol) - person morhook; 01.08.2017
comment
@morhook: Извините, вопрос нуба - это похоже на файл web.config на стороне сервера, верно? У меня нет доступа или контроля над серверной частью приложения. Я просто беру его из своего модульного теста. - person AngieM; 03.08.2017
comment
@AngieM, по моему опыту, нет вопросов от новичков. Для вашего примера модульного тестирования вы можете создать app.config в своем проекте модульного теста. Если вызов мыла выполняется внутри веб-проекта, вы должны сделать это на web.config (если сервер предоставляет API-интерфейс мыла, я не уверен, работает ли это, но похоже, что это тоже произойдет). Извините за долгое объяснение - person morhook; 05.08.2017
comment
Этот ответ не создает мыльный конверт, он просто сериализуется в xml. Как получить запрос на мыльный конверт? - person Ali Karaca; 18.05.2018

Попробуйте Fiddler2, он позволит вам проверять запросы и ответы. Возможно, стоит отметить, что Fiddler работает как с трафиком http, так и с https.

person Aaron Fischer    schedule 19.11.2008
comment
Это зашифрованная служба https. - person Andrew Harry; 20.11.2008
comment
Fiddler может расшифровать https-трафик - person Aaron Fischer; 20.11.2008
comment
Я считаю, что это решение лучше, чем добавление трассировки в файл web / app.config. Спасибо! - person andyuk; 18.09.2009
comment
Для меня это было лучшее решение, чем метод расширения. +1 - person Nullius; 08.07.2013
comment
Но использование system.diagnostics в файле конфигурации не требует установки стороннего приложения. - person Azat; 17.10.2013
comment
Fiddler потрясающий и простой в использовании, единственная проблема с ним заключается в том, что вы, например, не можете войти на общий хостинг. Поскольку вы не можете установить его там, и если сервер выполняет запрос, вам остается только опция SoapExtension. - person Pavel Donchev; 10.06.2014
comment
Это довольно просто для новичков в C #;) - person Mohamed Taher Alrefaie; 17.09.2014
comment
@AaronFischer: Будет ли Fiddler работать с мыльными сообщениями, отправляемыми через зашифрованный VPN? - person Our Man in Bananas; 09.03.2016

Похоже, что решение Тима Картера не работает, если при обращении к веб-ссылке возникает исключение. Я пытался получить необработанный веб-резонанс, чтобы я мог изучить его (в коде) в обработчике ошибок после того, как возникнет исключение. Однако я обнаружил, что журнал ответов, записанный методом Тима, пуст, когда вызов вызывает исключение. Я не совсем понимаю код, но похоже, что метод Тима врезается в процесс после того момента, когда .Net уже аннулировал и отбросил веб-ответ.

Я работаю с клиентом, который вручную разрабатывает веб-службу с помощью низкоуровневого кодирования. На этом этапе они добавляют свои собственные сообщения об ошибках внутреннего процесса в виде сообщений в формате HTML в ответ ПЕРЕД ответом в формате SOAP. Конечно, автоматическая веб-ссылка на .Net взрывается по этому поводу. Если бы я мог получить необработанный HTTP-ответ после создания исключения, я мог бы искать и анализировать любой SOAP-ответ в смешанном возвращающемся HTTP-ответе и знать, получили ли они мои данные нормально или нет.

Позже ...

Вот решение, которое действительно работает даже после выполнения (обратите внимание, что я только после ответа - тоже могу получить запрос):

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;
        }
    }
}

Вот как вы настраиваете это в файле конфигурации:

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

«TestCallWebService» следует заменить на имя библиотеки (это оказалось именем тестового консольного приложения, в котором я работал).

Вам действительно не нужно переходить на ChainStream; вы сможете сделать это проще из ProcessMessage как:

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.Stream, это должен быть поток только для чтения, который вы можете использовать для проверки данных на этом этапе. Это ошибка, потому что, если вы читаете поток, последующая обработка приводит к ошибкам без обнаруженных данных (поток был в конце), и вы не можете сбросить позицию в начало.

Интересно, что если вы используете оба метода, ChainStream и ProcessMessage, метод ProcessMessage будет работать, потому что вы изменили тип потока с ConnectStream на MemoryStream в ChainStream, а MemoryStream разрешает операции поиска. (Я пробовал преобразовать ConnectStream в MemoryStream - не разрешено.)

Итак ... Microsoft должна либо разрешить операции поиска для типа ChainStream, либо сделать SoapMessage.Stream действительно доступной только для чтения копией, как и должно быть. (Напишите своему конгрессмену и т. Д.)

Еще один момент. После создания способа получить необработанный HTTP-ответ после исключения я все еще не получил полного ответа (как определено анализатором HTTP). Это произошло потому, что когда веб-служба разработки добавляла сообщения об ошибках HTML в начало ответа, она не настраивала заголовок Content-Length, поэтому значение Content-Length было меньше размера фактического тела ответа. Все, что я получил, это количество символов в значении Content-Length - остальные отсутствовали. Очевидно, что когда .Net читает поток ответа, он просто считывает количество символов Content-Length и не допускает, чтобы значение Content-Length могло быть ошибочным. Это так и должно быть; но если значение заголовка Content-Length неверно, единственный способ получить все тело ответа - это использовать сниффер HTTP (я использую HTTP Analyzer из http://www.ieinspector.com).

person Chuck Bevitt    schedule 09.04.2010

Вот упрощенная версия главного ответа. Добавьте это в элемент <configuration> вашего web.config или App.config файла. Он создаст trace.log файл в папке bin/Debug вашего проекта. Или вы можете указать абсолютный путь к файлу журнала, используя атрибут initializeData.

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

Он предупреждает, что атрибуты maxdatasize и tracemode не разрешены, но они увеличивают объем данных, которые могут быть зарегистрированы, и избегают регистрации всего в шестнадцатеричном формате.

person Collin Anderson    schedule 03.01.2020

Я бы предпочел, чтобы фреймворк вел регистрацию за вас, подключив поток журналирования, который регистрируется по мере того, как фреймворк обрабатывает этот базовый поток. Следующее не так чисто, как хотелось бы, поскольку вы не можете выбрать между запросом и ответом в методе ChainStream. Вот как я с этим справляюсь. С благодарностью Джону Ханне за отмену идеи стрима

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);
        }
    }
}
person Community    schedule 09.03.2009
comment
@TimCarter, у меня это сработало, единственное, что я удалил, это клиентская часть, которая дает мне имя с двоеточием, вызывая исключение. Итак, как только я удалю эту строку, она отлично подойдет тем, кто хочет иметь один файл для каждого запроса / ответа. Единственное, что можно добавить, - это что-то очевидное, если вы читаете другие ответы, и это то, что вам нужно добавить узел web.config, чтобы указать soapExtension. Спасибо! - person netadictos; 24.04.2017

Вы не указали, какой язык используете, но предполагая, что C # / .NET, вы можете использовать Расширения SOAP.

В противном случае используйте сниффер, например Wireshark.

person rbrayb    schedule 19.11.2008
comment
Да, попробовал wirehark, он может показать мне только информацию заголовка, содержимое мыла зашифровано. - person Andrew Harry; 20.11.2008
comment
Это может быть потому, что вы используете https. Расширения SOAP, насколько я помню, работают на более высоком уровне, поэтому вы должны иметь возможность видеть данные после того, как они были расшифрованы. - person rbrayb; 20.11.2008
comment
Используйте Fiddler вместо Wireshark, он расшифровывает https из коробки. - person Rodrigo Strauss; 05.02.2013

Я понимаю, что довольно опаздываю на вечеринку, и, поскольку язык на самом деле не был указан, вот решение 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 объекта, который вы пытаетесь передать веб-службе (реально это должно работать и для любого объекта, который вы хотите передать ему).

В качестве побочного примечания вызов replace в функции перед возвратом xml должен вырезать символы vbCrLf из вывода. У меня их было несколько в сгенерированном xml, однако это, очевидно, будет зависеть от того, что вы пытаетесь сериализовать, и я думаю, что они могут быть удалены во время отправки объекта в веб-службу.

person user2366842    schedule 09.10.2015
comment
Для тех, кто дал мне пощечину отрицательным голосом, пожалуйста, дайте мне знать, что мне не хватает / что можно улучшить. - person user2366842; 31.07.2018