调用Web服务时出现XML错误

Ken*_*n D 5 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类型的对象.".
  • 当我调用该方法(使用US代理类)时,我得到一个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服务选择不同的命名空间?

inq*_*ive 2

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

现在,您可以使用一个客户端仅连接到其自己的服务器。因此使用 EU 客户端连接到 EU。使用美国客户端连接到美国。这里的客户端是指代理(add-service-ref 生成的东西)

消费者代码可能想要使用服务,而不管其位置如何。为此,我建议使用适配器模式。所以它会是这样的:

你的代码:

 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();
     }
Run Code Online (Sandbox Code Playgroud)

这样,您的客户端代码将免受实际端点的影响。作为替代方法,您可以通过服务客户端的代码配置直接重新配置端点,但我不建议这样做。当欧盟人决定做出一些改变而美国人却没有这样做时,这打破了这一时刻。最好,选择适配器模式。