Как передать заголовок Soap, если WSDL его не определяет?

У меня есть веб-служба, которую я вызываю, и их опубликованный WSDL на самом деле не определяет большую часть службы, 3/4 из них вам придется впоследствии создавать вручную.

У меня проблема в том, что им нужен SoapHeader с некоторой конкретной информацией, но у меня нет никакого способа сделать это. Единственные реальные вещи, которые у меня есть для службы, - это созданный прокси-метод (MyMethod), которому я могу передать свое сообщение. Как я могу также установить/отправить заголовок мыла?

Все сервисы, которые у меня были, я смог использовать автоматически привязываемые элементы из Visual Studio.


person Mitchel Sellers    schedule 14.02.2009    source источник


Ответы (4)


Я смог сделать это, изменив автоматически сгенерированный прокси-код вручную и просто внедрив класс, унаследовавший «SoapHeader», и добавив атрибут к методу!

Я не могу повторно сгенерировать или обновить прокси-сервер, но он выполнил свою работу и занял всего 15 минут.

person Mitchel Sellers    schedule 18.02.2009

Довольно старый пост, но может быть полезен для других.

При интеграции WSDL в Visual Studio вы получаете новый класс, производный от SoapHttpClientProtocol в новом пространстве имен.

К счастью, этот класс является частичным, это означает, что вы можете расширить его в своем коде, чтобы сделанные вами изменения не перезаписывались при обновлении из WSDL.

Мой сгенерированный класс WSDL:

namespace TheServiceNameSpace {
          public partial class TheClassName : System.Web.Services.Protocols.SoapHttpClientProtocol {
         //Class Code
     }
}

Чтобы добавить собственный заголовок, я добавляю в свой проект новый файл cs со следующим содержимым:

namespace TheServiceNameSpace 
{
    public partial class SecurityHeader : SoapHeader
    {
        public String username { get; set; }
        public String password { get; set; }
        public String apikey { get; set; }
    }

    public partial class TheClassName
    {
        public SecurityHeader SEC = new SecurityHeader() { username = "xxxx", password = "xxxx", apikey = "xxxx" };

        protected override XmlWriter GetWriterForMessage(SoapClientMessage message, int bufferSize)
        {
            message.Headers.Add(SEC);
            return base.GetWriterForMessage(message, bufferSize);
        }
    }
}

Что он делает, так это:

  • 1. Создайте собственный заголовок SOAP, содержащий ожидаемые переменные.
  • 2 - Расширьте сгенерированный класс, чтобы добавить ссылку на новый заголовок
  • 3 - Переопределить метод GetWriterForMessage, чтобы я мог добавить свой заголовок в запрос, который будет отправлен в службу.
person FKA    schedule 04.06.2016
comment
Когда я это делаю, я получаю что-то, как показано ниже, но я не могу получить префикс wsse. Что мне не хватает? ‹soap:Header› ‹Security xmlns=localhost:80.....› ‹UserNameToken› ‹UserName›dfgsfd ‹/UserName› ‹Password›sdfgsfd‹/Password› ‹/UserNameToken› ‹/Security› ‹/soap:Header› - person Yoismel; 27.01.2020

Возможно, вы захотите см. Добавление неявных заголовков SOAP в C# на форуме AdSense API (в архиве), чтобы узнать что-то подобное; это кажется выполнимым, но много работы... или вы можете создать весь запрос вручную (еще хуже...).

person Marc Gravell    schedule 14.02.2009

Если вам нужен точный контроль над тем, как отображается xml заголовка мыла (происходит при взаимодействии с веб-службой, написанной на java), вы всегда можете переопределить весь рендеринг, реализуя IXmlSerializable

[XmlRoot("customHeader", Namespace = "http://somecompany.com/webservices/security/2012/topSecret")]
public class customHeader: SoapHeader, IXmlSerializable
{
    public customHeader()
    {
        Actor = "http://schemas.xmlsoap.org/soap/actor/next";
        MustUnderstand = false;
    }

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
        //throw new NotImplementedException();
    }

    public void ReadXml(XmlReader reader)
    {
        //throw new NotImplementedException();
    }

    public void WriteXml(XmlWriter writer)
    {
        writer.WriteAttributeString("soap:actor", Actor);
        writer.WriteAttributeString("soap:mustUnderstand", MustUnderstand ? "1" : "0");
        writer.WriteRaw("some encrypted data");
        //get it exactly the way you want it in here without mucking with Xml* property attributes for hours on end
        //writer.WriteElement(...);
    }
}
person viggity    schedule 10.07.2012