Pregunta

Tengo un servicio web ASP.NET similar 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
    }
}

Estoy llamando al servicio web desde 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)

El problema que encuentro es que cuando el XML llega al método ProcessMessage, el servicio web ha agregado un espacio de nombres predeterminado en el camino.es decir.si configuro un punto de interrupción dentro de ProcessMessage (mensaje XmlDocument), veo:

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

Cuando capturo paquetes en el cable, puedo ver que el XML enviado por el kit de herramientas SOAP es ligeramente diferente del enviado por el cliente .NET WS.El kit de herramientas SOAP envía:

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

Mientras el cliente .NET envía:

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

Ha pasado tanto tiempo desde que utilicé el kit de herramientas ASP/SOAP para llamar a servicios web .NET, que no puedo recordar todos los trucos inteligentes/SOAP-fu que solía utilizar para solucionar cosas como esta.

¿Algunas ideas?Una solución es crear un proxy .NET invocable por COM que tome el XML como un parámetro de cadena y llame al WS en mi nombre, pero es una capa adicional de complejidad/trabajo que esperaba no hacer.

¿Fue útil?

Solución 3

Resolví esto:

El cliente SOAP pedido el nodo estaba recogiendo el espacio de nombres predeterminado de:

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

Agregar un espacio de nombres predeterminado vacío al XML enviado por el cliente ASP anula este comportamiento:

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

Otros consejos

Kev,

Encontré la solución, pero no es trivial.

Debe crear una implementación personalizada de IHeaderHandler que cree los encabezados adecuados.

Aquí hay un buen paso a paso:

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

EDITAR:Vi tu actualización.Buena solución, es posible que quieras marcar este enlace como favorito :D

Supongo que usted tiene acceso al código de Servicios, no solo al cliente consumidor, ¿verdad?

Simplemente extraiga el espacio de nombres del XmlDocument como primera parte del 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;
    }
}

Entonces:

[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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top