2009-11-13 9 views
11

Sto provando a creare un servizio C# in .NET 3.5 che supporti sia SOAP - e mostri WSDL - sia REST.Fare un singolo servizio WCF supporta sia SOAP, REST e WSDL

Il servizio SOAP e la generazione WSDL sono stati abbastanza semplici da utilizzare con le classi ServiceHost e BasicHttpBinding. Ha funzionato e il cliente era felice.

Poiché il SOAP chiama tutti i parametri semplici utilizzati, gli sviluppatori client hanno richiesto un'interfaccia REST per alcuni comandi. Così ho cambiato la classe ServiceHost in WebServiceHost, aggiunto gli attributi WebInvoke e WebGet, aggiunto una classe WebHttpBinding e il bingo - REST e SOAP stavano lavorando entrambi su un servizio. Benissimo, cambia un'interfaccia e sia REST che SOAP hanno le novità.

Ma un problema: il WSDL non viene più generato. Non riuscivo a navigare su http://server/service?wsdl e ottenere il file WSDL. Controllo dei documenti MSDN, sembra essere il comportamento per un valore predefinito WebServiceHost.

Domanda: è possibile sovrascrivere questo comportamento per ottenere il WSDL? Non ha lo stesso URL di prima - può cambiare - ma ho solo bisogno di avere qualche URL in servizio per ottenere il WSDL per quegli sviluppatori SOAP.

+0

Ciao Jason, mi piacerebbe sapere se stai ancora utilizzando questo approccio e come funziona o non funziona per te. Stai scoprendo che devi duplicare qualsiasi metodo (la logica principale) per supportare entrambi? – schmoopy

+0

Ho appena dovuto creare due endpoint e aggiungere un attributo extra a ciascun comando. –

+0

problema simile con la soluzione. http://social.msdn.microsoft.com/Forums/en/wcf/thread/845d0bbd-52b4-420f-bf06-793d53ef93ba – maciejW

risposta

4

Quando si dice "aggiunta una classe WebHttpBinding", sembra che si stia eseguendo molta della configurazione nel codice anziché nei file di configurazione.

In tal caso, provare a spostare la configurazione nel file di configurazione. Quindi creare 2 endpoint per il contratto REST e un SOAP, con 2 indirizzi e collegamenti diversi.

+0

Faccio tutte le configurazioni nel codice, non nei file di configurazione. Una soluzione consiste nell'utilizzare due endpoint e questa soluzione funziona perfettamente. Speravo di utilizzare un singolo endpoint; una singola porta e un URL di root. –

+1

Non penso che si possa ottenere un WSDL da un WebHttpBinding Endpoint. –

4

Ma un problema: il WSDL non è più generato. Non riuscivo a cercare http://server/service?wsdl e ottenere il file WSDL . Controllo dei documenti MSDN, , che sembra essere un comportamento per un WebServiceHost predefinito .

Sì, questo è uno degli svantaggi di REST: niente più WSDL, nessuna descrizione del servizio più leggibile dalla macchina. Devi sperare che il fornitore di servizi ti fornisca una documentazione utilizzabile e aggiornata su ciò che puoi fare.

Non c'è WSDL per REST - periodo. Non può essere attivato o altro - semplicemente non esiste.

Ci sono alcuni sforzi in corso per fornire qualcosa di simile - chiamato WADL (linguaggio Descrizione applicazione Web), ma per quanto ne so, è ancora lontano da uno standard stabilito con qualsiasi mezzo. Vedi anche: Do we need WADL?

+0

Posso capire che REST non ha WSDL, ma tieni presente che il servizio sta gestendo contemporaneamente sia le richieste REST sia quelle SOAP. È solo che i client SOAP non possono più richiedere un WSDL. L'obiettivo era di avere un unico servizio, con una singola porta di ascolto, che potesse servire sia REST, SOAP e WSDL, tutto basato sul percorso dell'URL. –

0

Circa, 2007, WSDL v2.0 dovrebbe essere in grado di descrivere i servizi RESTful. Ho trovato che con WCF in. Net v4.0, che il WDSL generato da un servizio puramente RESTful non è valido (WSDL v1.0?).

Ho creato un progetto simile che espone sia SOAP e gli endpoint RESTful, e abilitato questo, come avete fatto, modificando l'interfaccia come ad esempio:

// Get all Categories - complex object response 
    [OperationContract]        // categories 
    [WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "GetAllCategories")] 
    CategoryCollection GetAllCategories();   // SubSonic object 
    [OperationContract]        // categories - respond with a JSON object 
    [WebGet(ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "GetAllCategories.JSON")] 
    CategoryCollection GetAllCategoriesJSON();  // SubSonic object 

Un avvertimento a questo è che tutti i parametri di input deve ora essere di tipo stringa per tutte le richieste SOAP.

Qualsiasi modo per aggirare questo?

+0

C'è un modo per esporre esattamente lo stesso metodo in SOAP e REST invece di aggiungere un nuovo metodo per ogni vecchio metodo soap? –