Pergunta

Eu tenho um webservice ASP.NET semelhante a:

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

Estou ligando para o serviço web do ASP usando algo como:

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)

O problema que estou encontrando é que quando o XML atinge o método ProcessMessage, o encanamento do serviço da web adicionou um namespace padrão ao longo do caminho.ou sejase eu definir um ponto de interrupção dentro de ProcessMessage(XmlDocument message) vejo:

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

Quando capturo pacotes na rede, posso ver que o XML enviado pelo kit de ferramentas SOAP é um pouco diferente daquele enviado pelo cliente .NET WS.O kit de ferramentas SOAP envia:

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

Enquanto o cliente .NET envia:

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

Já faz muito tempo que não usei o kit de ferramentas ASP/SOAP para chamar serviços da web .NET, não consigo me lembrar de todos os truques inteligentes/SOAP-fu que usei para contornar coisas como essa.

Alguma ideia?Uma solução é criar um proxy .NET que pode ser chamado por COM que usa o XML como um parâmetro de string e chama o WS em meu nome, mas é uma camada extra de complexidade/trabalho que eu esperava não fazer.

Foi útil?

Solução 3

Eu resolvi isso:

O cliente SOAP solicitar node estava pegando o namespace padrão de:

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

Adicionar um namespace padrão vazio ao XML enviado pelo cliente ASP substitui este comportamento:

xmlMessage = "<request xmlns=''><task>....various xml</task></request>"

Outras dicas

Kev,

Encontrei a solução, mas não é trivial.

Você precisa criar uma implementação personalizada de IHeaderHandler que crie os cabeçalhos adequados.

Tem um bom passo a passo aqui:

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

EDITAR:Eu vi sua atualização.Boa solução alternativa, você pode querer marcar este link de qualquer maneira: D

Presumo que você tenha acesso ao código dos Serviços, não apenas ao cliente consumidor, certo?

Basta extrair o namespace do XmlDocument como a primeira parte do método.

Algo como:

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

Então:

[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...
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top