2013-08-20 2 views
5

Ho 4 portali (WW, UE, AU, USA), ognuno di essi ha il proprio servizio Web (tramite PHP che significa che non ho il controllo).Errore XML durante la chiamata al servizio web

Per questi 4 servizi Web, ho 4 client (generato da VS.Net Aggiungi riferimento Web).

C'è un metodo chiamato CommonMethod è lo stesso su tutti i servizi Web, restituisce un oggetto di tipo CommonClass.

  • Quando chiamo che il metodo (utilizzando classe proxy UE) sto ottenendo un InvalidOperationException There is an error in XML document (2, 615)., e l'InnerException dice "Impossibile assegnare oggetto di tipo NS.com.AU.CommonClass ad un oggetto di tipo NS.com. EU.CommonClass. ".
  • Quando chiamo quel metodo (utilizzando la classe proxy US) ricevo un InvalidOperationException There is an error in XML document (2, 615)., e InnerException dice "Impossibile assegnare l'oggetto di tipo NS.com.AU.CommonClass a un oggetto di tipo NS.com.US.CommonClass . ".
  • Quando chiamo quel metodo (utilizzando la classe proxy AU), non viene generata alcuna eccezione.
  • Quando chiamo quel metodo (utilizzando la classe proxy WW) sto ottenendo un InvalidOperationException There is an error in XML document (2, 615)., e InnerException dice "Impossibile assegnare l'oggetto di tipo NS.com.AU.CommonClass a un oggetto di tipo NS.com.WW.CommonClass . ".

ho cercato nel web per tale errore, beh è XML in modo un sacco di roba irrilevante si avvicina e non riusciva a trovare qualcosa di utile.

Ora ho notato che i 4 servizi Web utilizzano lo stesso spazio dei nomi nei documenti WSDL (xmlns: tns = "urna: rambo.com: RamboComApi"). Può essere questa la fonte di confusione e eccezione di tipo casting? Devo dire agli autori dei servizi web di scegliere diversi namespace per ogni servizio web?

+0

Sembra che il codice stia creando un tipo di oggetto NS.com.AU.CommonClass e l'unica classe proxy che ha un tipo corrispondente è la classe proxy AU. Tutti gli altri si lamentano che stai cercando di assegnare NS.com.AU.CommonClass a NS.com.EU.CommonClass, NS.com.US.CommonClass o NS.com.WW.CommonClass.Se i loro WSDL sono identici, dovresti essere in grado di utilizzare la stessa classe proxy ma solo modificare l'URL di destinazione. – Dijkgraaf

+0

Grazie, intendi qualcosa come [questo] (http://stackoverflow.com/a/16407382/502436)? –

+1

No, non dovresti cambiare gli spazi dei nomi, basta usare il proxy che hai creato per AU e basta impostare l'URL di destinazione per chiamare il servizio web appropriato. – Dijkgraaf

risposta

2

I servizi Web potrebbero essere identici, ma non sono gli stessi. Cioè, non è che lo stesso codice PHP sia ospitato in tutti i posti. il codice di servizio PHP potrebbe essere gestito separatamente. ciò significa che tu devi avere quattro client nel tuo codice. 4 riferimenti di servizio. Che stai facendo molto bene.

ora, è possibile utilizzare un client per connettersi solo al proprio server. quindi utilizzare il client UE per connettersi all'UE. usa il client degli Stati Uniti per connetterti agli Stati Uniti. qui per client intendo proxy (la cosa add-service-ref genera)

Il codice utente potrebbe voler consumare servizi indipendentemente dalla loro posizione. per questo consiglio di usare Adapter Pattern. quindi sarebbe qualcosa di simile:

il tuo codice:

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 questo modo, il vostro codice cliente sarà schermato dagli endpoint effettivi. Come approccio alternativo è possibile riconfigurare gli endpoint direttamente tramite la configurazione in codice del client di servizio, ma non lo raccomanderò. Rompe il momento in cui il ragazzo dell'UE decide di fare un piccolo cambiamento che il ragazzo degli Stati Uniti non ha fatto. meglio, vai per modello adattatore.

+0

voglio aggiungere a @inquisitive answer (che penso sia la risposta), che puoi violinista il tuo client e guardare come viene chiamato lo stesso servizio per tutte le chiamate e questo è il problema. – Liran