Вызов веб-службы ASP.NET из ASP с использованием SOAPClient - PullRequest
3 голосов
/ 21 августа 2008

У меня есть веб-сервис ASP.NET со следующими параметрами:

[WebService(Namespace = "http://internalservice.net/messageprocessing")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
public class ProvisioningService : WebService
{
    [WebMethod]
    public XmlDocument ProcessMessage(XmlDocument message)
    {
        // ... do stuff
    }
}

Я вызываю веб-сервис из ASP, используя что-то вроде:

provWSDL = "http://servername:12011/MessageProcessor.asmx?wsdl"
Set service = CreateObject("MSSOAP.SoapClient30")
service.ClientProperty("ServerHTTPRequest") = True
Call service.MSSoapInit(provWSDL)

xmlMessage = "<request><task>....various xml</task></request>"
result = service.ProcessMessage(xmlMessage)

Проблема, с которой я сталкиваюсь, заключается в том, что, когда XML достигает метода ProcessMessage, в процессе подключения к веб-службе добавляется пространство имен по умолчанию. то есть, если я устанавливаю точку останова внутри ProcessMessage (сообщение XmlDocument), я вижу:

<request xmlns="http://internalservice.net/messageprocessing">
  <task>....various xml</task> 
</request>

Когда я перехватываю пакеты в сети, я вижу, что XML, отправленный инструментарием SOAP, немного отличается от того, который отправляет клиент .NET WS. Набор инструментов SOAP отправляет:

<SOAP-ENV:Envelope 
    xmlns:SOAPSDK1="http://www.w3.org/2001/XMLSchema" 
    xmlns:SOAPSDK2="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:SOAPSDK3="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Body>
        <ProcessMessage xmlns="http://internalservice.net/messageprocessing">
            <message xmlns:SOAPSDK4="http://internalservice.net/messageprocessing">
                <request>
                    <task>...stuff to do</task>
                </request>
            </message>
        </ProcessMessage>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Пока клиент .NET отправляет:

<soap:Envelope 
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <ProcessMessage xmlns="http://internalservice.net/messageprocessing">
            <message>
                <request xmlns="">
                    <task>...stuff to do</task>
                </request>
            </message>
        </ProcessMessage>
    </soap:Body>
</soap:Envelope>

Прошло так много времени с тех пор, как я использовал инструментарий ASP / SOAP для вызова веб-сервисов .NET, я не могу вспомнить все хитрые приемы / SOAP-fu, которые я использовал, чтобы обойти подобные вещи.

Есть идеи? Одним из решений является создание вызываемого COM-прокси .NET, который принимает XML в качестве строкового параметра и вызывает WS от моего имени, но это дополнительный уровень сложности / работы, который я надеялся не выполнять.

Ответы [ 3 ]

1 голос
/ 21 августа 2008

Кев,

Я нашел решение, но оно не тривиально.

Вам необходимо создать собственную реализацию IHeaderHandler, которая создает правильные заголовки.

Здесь есть хороший шаг за шагом:

http://msdn.microsoft.com/en-us/library/ms980699.aspx

РЕДАКТИРОВАТЬ: Я видел ваше обновление. Хороший обходной путь, вы можете добавить эту ссылку в закладки, независимо от того: D

0 голосов
/ 21 августа 2008

Я решил это:

Клиент SOAP запрос узел выбирал пространство имен по умолчанию из:

<ProcessMessage xmlns="http://internalservice.net/messageprocessing">

Добавление пустого пространства имен по умолчанию к XML, отправляемому клиентом ASP, отменяет это поведение:

xmlMessage = "<request xmlns=''><task>....various xml</task></request>"
0 голосов
/ 21 августа 2008

Я так понимаю, у вас есть доступ к коду Сервисов, а не только к клиенту, верно?

Просто вытащите пространство имен из XmlDocument в качестве первой части метода.

Что-то вроде:

XmlDocument changeDocumentNamespace(XmlDocument doc, string newNamespace) 
{   
    if (doc.DocumentElement.NamespaceURI.Length > 0) 
    {
        doc.DocumentElement.SetAttribute("xmlns", newNameSpace);
        XmlDocument newDoc = new XmlDocument();
        newDoc.LoadXml(doc.OuterXml);
        return newDoc;
    }
    else 
    {
        return doc;
    }
}

Тогда:

[WebService(Namespace = "http://internalservice.net/messageprocessing")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
public class ProvisioningService : WebService
{
    [WebMethod]
    public XmlDocument ProcessMessage(XmlDocument message)
    {
        message = changeDocumentNamespace(message,String.Empty);
        // Do Stuff...
    }
}
...