5

I have 4 portals (WW, EU, AU, US), every one of them has its own web service (through PHP which means I do not have control over).

For those 4 web services, I have 4 clients (generated by VS.Net Add Web Reference).

There is a method called CommonMethod it is the same on all web services, returns an object of type CommonClass.

  • When I call that method (using EU proxy class) I am getting an InvalidOperationException There is an error in XML document (2, 615)., and the InnerException says "Cannot assign object of type NS.com.AU.CommonClass to an object of type NS.com.EU.CommonClass.".
  • When I call that method (using US proxy class) I am getting an InvalidOperationException There is an error in XML document (2, 615)., and the InnerException says "Cannot assign object of type NS.com.AU.CommonClass to an object of type NS.com.US.CommonClass.".
  • When I call that method (using AU proxy class), No exception is thrown.
  • When I call that method (using WW proxy class) I am getting an InvalidOperationException There is an error in XML document (2, 615)., and the InnerException says "Cannot assign object of type NS.com.AU.CommonClass to an object of type NS.com.WW.CommonClass.".

I searched the web for such error, well it is XML so a lot of irrelevant stuff comes up and could not find something useful.

Now I noticed, the 4 web services are using the same namespace in their WSDL documents (xmlns:tns="urn:rambo.com:RamboComApi"). Can this be the source of confusion and type-casting exception? Should I tell the authors of the web services to choose different namespace for each web service?

Ken D
  • 5,880
  • 2
  • 36
  • 58
  • It looks like your code is creating an object type of NS.com.AU.CommonClass and the only proxy class that has a matching type is the AU proxy class. All the others complain that you are trying to assign NS.com.AU.CommonClass to NS.com.EU.CommonClass, NS.com.US.CommonClass or NS.com.WW.CommonClass. If their WSDLs are identical you should be able to use the same proxy class but just change the target URL. – Dijkgraaf Aug 29 '13 at 03:45
  • Thanks, do you mean something like [this](http://stackoverflow.com/a/16407382/502436)? – Ken D Aug 29 '13 at 04:35
  • 1
    No, you shouldn't have to change the namespaces at all, just use the proxy you created for AU and just set the target URL to call the appropriate web service. – Dijkgraaf Aug 29 '13 at 20:24
  • Can you give us a snippet of the code around where you are calling the proxy class? – Dijkgraaf Aug 31 '13 at 05:49

1 Answers1

2

The web services might be identical, but they are not the same. That is, it is not like that the same PHP code is hosted at all the places. the PHP service code might be maintained separately. what this means is that you must have four clients in your code. 4 service references. That you are doing very well.

now, you can use one client to connect only to its own server. so use EU client to connect to EU. use US client to connect to US. here by client i mean proxy (the thing add-service-ref generates)

The consumer code might want to consume services irrespective of their location. for that i recommend using Adapter Pattern. so it would be something like this:

your code:

 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();
     }

in this way, your client code will be shielded from the actual endpoints. As an alternate approach you can reconfigure the endpoints directly though in-code-configuration of teh service client, but i wont recommend that. It breaks the moment when the EU guy decides to make a little change which US guy did not. best, go for adapter pattern.

inquisitive
  • 3,549
  • 2
  • 21
  • 47
  • i want to add to @inquisitive answer ( which i think is the answer ), that you can fiddler your client and watch as the same service is being called for all calls and that is the problem. – Liran Sep 01 '13 at 09:33