调用Web服务时出现XML错误

时间:2013-08-20 10:37:09

标签: xml web-services namespaces

我有4个门户网站(WW,EU,AU,US),每个门户网站都有自己的网络服务(通过PHP,这意味着我无法控制)。

对于这4个Web服务,我有4个客户端(由VS.Net添加Web引用生成)。

有一个名为CommonMethod的方法,它在所有Web服务上都是相同的,返回类型为CommonClass的对象。

  • 当我调用该方法时(使用EU代理类)我得到一个InvalidOperationException There is an error in XML document (2, 615).,并且InnerException说“无法将类型为NS.com.AU.CommonClass的对象分配给NS.com类型的对象.EU.CommonClass。“
  • 当我调用该方法时(使用美国代理类)我得到一个InvalidOperationException There is an error in XML document (2, 615).,而InnerException说“无法将类型为NS.com.AU.CommonClass的对象分配给NS.com类型的对象.US.CommonClass。“
  • 当我调用该方法时(使用AU代理类),不会抛出任何异常。
  • 当我调用该方法时(使用WW代理类)我得到一个InvalidOperationException There is an error in XML document (2, 615).,而InnerException说“无法将类型为NS.com.AU.CommonClass的对象分配给NS.com类型的对象.WW.CommonClass。“

我在网上搜索了这样的错误,因为它是XML所以很多不相干的东西出现了,找不到有用的东西。

现在我注意到,4个Web服务在其WSDL文档中使用相同的命名空间(xmlns:tns =“urn:rambo.com:RamboComApi”)。这可能是混淆和拼写异常的根源吗?我是否应该告诉Web服务的作者为每个Web服务选择不同的命名空间?

1 个答案:

答案 0 :(得分:2)

Web服务可能完全相同,但它们并不相同。也就是说,并不是所有地方都托管相同的PHP代码。 PHP服务代码可能会单独维护。这意味着您必须在您的代码中有四个客户端。 4个服务参考。你做得很好。

现在,您可以使用一个客户端仅连接到自己的服务器。所以使用欧盟客户连接到欧盟。使用美国客户连接到美国。在这里由客户端我的意思是代理(事物add-service-ref生成)

消费者代码可能希望使用服务,而不管其位置如何。为此,我建议使用 Adapter Pattern 。所以它会是这样的:

您的代码:

 IServiceAdapter adapter = ServiceFactory.createAdapter("EU");
 adapter.DoStuff();
 ...


   IServiceAdapter                                 AdapterFactory
   ---------------                                 --------------
   void  DoStuff1();                IServiceAdapter  CreateAdapter(string Target) {
   int   DoStuff2();                    switch Target {
                                            case "EU"
                                                return new EUServiceAdapter();
                                                break;

                                            case "US"
                                                return new USServiceAdapter();
                                                break;
                                        }
                                    }



           EU_ServiceAdpater                       
        -----------------------                   
     (Implement  IServiceAdapter)                 

     void DoStuff1() {
          ServiceReference_EU.ServiceObject1.DoStuff1();
     }

     int DoStuff2() {
          return ServiceReference_EU.ServiceObject1.DoStuff2();
     }




           US_ServiceAdpater                       
        -----------------------                   
     (Implement  IServiceAdapter)                 

     void DoStuff1() {
          ServiceReference_US.ServiceObject1.DoStuff1();
     }

     int DoStuff2() {
          return ServiceReference_US.ServiceObject1.DoStuff2();
     }
以这种方式,您的客户端代码将屏蔽实际端点。作为替代方法,您可以通过服务客户端的代码配置直接重新配置端点,但我不建议这样做。它打破了欧盟人决定做出一点变化的那一刻,美国人没有做出改变。最好,去适配器模式。