Получите сообщение SOAP перед отправкой его в WebService в .NET.

Я вызываю внешний веб-сервис HTTPS.

Чтобы проверить, что не так, владельцу нужен запрос SOAP, который я отправляю.

У меня есть веб-ссылка и сгенерированный прокси-класс, сгенерированный VS 2008...

Есть ли способ увидеть сообщение SOAP перед отправкой?

Я думаю в некотором .net-коде... потому что Sniffers, которого я пробовал, не "видел" вызов webservice, не знаю почему.

Ответ 1

Что вам нужно - это SoapExtension. Здесь есть несколько хороших примеров:

Как получить доступ к ответу SOAP

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

Ошибка XML Parse при обработке ответа SOAP

Одна из статей, связанных с: http://msdn.microsoft.com/en-us/magazine/cc164007.aspx

Также выполните поиск SO для: https://stackoverflow.com/search?q=SoapExtension

Ответ 2

Вы можете просто сериализовать объект запроса, прежде чем его вычесть, например:

var sreq = new SomeSoapRequest();

// ... fill in here ...

var serxml = new System.Xml.Serialization.XmlSerializer(sreq.GetType());
var ms = new MemoryStream();
serxml.Serialize(ms, sreq);
string xml = Encoding.UTF8.GetString(ms.ToArray());

// in xml string you have SOAP request

Ответ 3

Вы можете использовать IClientMEssageInspector и IEndpointBehavior для полного заполнения. Я нашел, что использование этого способа может фиксировать точный запрос на мыло, вероятно, как скрипач:

Создайте класс, подобный этому, в том же проекте:

public class ClientMessageInspector : System.ServiceModel.Dispatcher.IClientMessageInspector
    {
        #region IClientMessageInspector Members
        public string LastRequestXml { get; private set; }

        public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
        {

        }

        public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
        {
            string requestHeaderName = request.Headers.Action.Replace("urn:#",string.Empty);
            LastRequestXml = request.ToString();
            string serializedRequestFile = string.Format(requestHeaderName + "_request_{0}.xml", DateTime.Now.ToString("yyyyMMddHHmmss"));
            string exportedFolder = ConfigurationManager.AppSettings["SubmittedRequestXmLocation"];
            printSoapRequest(request, exportedFolder, serializedRequestFile);

            return request;
        }

        public void printSoapRequest(System.ServiceModel.Channels.Message request, string exportedFolder, string fileName)
        {
            if (exportedFolder.Equals(string.Empty))
                return;

            if (!Directory.Exists(exportedFolder))
            {
                Directory.CreateDirectory(exportedFolder);
            }
            string exportedFile = string.Format("{0}\\{1}", exportedFolder, fileName);
            if (File.Exists(exportedFile))
            {
                File.Delete(exportedFile);
            }

            string strRequestXML = request.ToString();
            XDocument xDoc = XDocument.Parse(strRequestXML);
            XmlWriter xw = XmlWriter.Create(exportedFile);
            xDoc.Save(xw);
            xw.Flush();
            xw.Close();
            LogOutput("Request file exported: " + exportedFile);

        }

    }

    public class CustomInspectorBehavior : IEndpointBehavior
    {
        private readonly ClientMessageInspector clientMessageInspector = new ClientMessageInspector();

        public string LastRequestXml
        {
            get { return clientMessageInspector.LastRequestXml; }
        }

        public string LastResponseXml
        {
            get { return clientMessageInspector.LastRequestXml; }
        }

        public void AddBindingParameters(
            ServiceEndpoint endpoint,
            System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
        }

        public void Validate(ServiceEndpoint endpoint)
        {
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            clientRuntime.MessageInspectors.Add(clientMessageInspector);
        }
    }

Затем вы можете вызвать его следующим образом:

ProxyClass _class = new ProxyClass();
var requestInterceptor = new CustomInspectorBehavior();
           _client.Endpoint.Behaviors.Add(requestInterceptor);

Когда вы вызываете метод службы, он автоматически выполняет перехватчик и печатает вывод. Используя этот способ, вы также можете манипулировать мыльным сообщением перед отправкой на сервер!

Ответ 4

Если вы работаете в более ограниченной среде и не имеете возможности использовать такое приложение, как Fiddler, вы можете сделать следующее:

  • Создайте веб-ссылку как обычно.
  • Напишите код для выполнения любого вызова веб-метода, который вы собираетесь ко мне.
  • Создайте новый проект ASP.NET по вашему выбору, я пошел с MVC 4.
  • Создайте обработчик или контроллер/действие и извлеките поток запросов следующим образом:

using (var reader = new System.IO.StreamReader(Request.InputStream)) { result = reader.ReadToEnd(); }

  • Поместите на него контрольную точку и запустите ее в режиме отладки.
  • На вашем клиенте установите URL-адрес запроса SOAP новому контроллеру/обработчику.
  • Запустите клиент. Вы должны поймать точку останова в своем веб-приложении со своим сообщением SOAP.

Это не идеальное или красивое решение, но если вы работаете в умеренно ограниченной среде, он выполняет свою работу.