使用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,我们都可能希望将此链接添加为书签