使用SOAPClient从ASP调用ASP.NET Web服务

时间:2020-03-05 18:41:23  来源:igfitidea点击:

我有一个ASP.NET Web服务,其中包括:

[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调用Web服务:

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方法时,Web服务管道沿途添加了默认名称空间。即如果我在ProcessMessage(XmlDocument message)内设置断点,则会看到:

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

当我捕获在线数据包时,我可以看到SOAP工具包发送的XML与.NET WS客户端发送的XML略有不同。 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 Web服务以来已经很长时间了,我不记得我曾经使用过的所有巧妙技巧/ SOAP-fu来解决此类问题。

有任何想法吗?一种解决方案是取消一个COM可调用的.NET代理,该代理将XML作为字符串参数并代表我调用WS,但这是我不希望做的另一层复杂性/工作。

解决方案

回答

我认为我们可以访问服务代码,而不仅仅是使用客户端吗?

只需将名称空间从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...
    }
}

回答

我解决了这个问题:

SOAP客户端请求节点从以下位置获取默认名称空间:

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

向ASP客户端发送的XML添加空的默认名称空间会覆盖此行为:

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

回答

凯夫(Kev)

我找到了解决方案,但它并不简单。

我们需要创建IHeaderHandler的自定义实现,以创建适当的标头。

这里有一个很好的循序渐进的步骤:

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

编辑:我看到了更新。不错的解决方法,无论:D,我们都可能希望将此链接添加为书签