2009-03-17 2 views
10

Sto lottando bene per ottenere quel momento "magico" in cui WCF è configurato bene e jQuery sta strutturando le sue richieste/risposte di comprensione in modo corretto.JQuery/WCF senza ASP.NET AJAX:

Ho un servizio:

<%@ ServiceHost Language="C#" Debug="true" Service="xxx.yyy.WCF.Data.ClientBroker" Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory" %> 

Questo è stato consigliato da un uomo Rick Strahl per evitare di dover definire i comportamenti all'interno di web.config.

mia interfaccia per il servizio WCF si trova in un altro assembly:

namespace xxx.yyy.WCF.Data 
{  
    [ServiceContract(Namespace = "yyyWCF")] 
    public interface IClientBroker 
    { 
     [OperationContract]   
     [WebInvoke(Method="POST",BodyStyle=WebMessageBodyStyle.Wrapped,ResponseFormat=WebMessageFormat.Json)] 
     IClient GetClientJson(int clientId);  
    } 
} 

La classe di servizio concreto è:

namespace xxx.yyy.WCF.Data 
{ 
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 
    class ClientBroker : IClientBroker 
    { 
     public IClient GetClientJson(int clientId) 
     { 
      IClient client=new Client(); 

      // gets and returns an IClient 
      return client; 
     } 
    } 
} 

mio iClient è una classe Entity Framework così è decorato con attributi/DataMember DataContract appropriatamente.

Sto provando a chiamare il servizio WCF utilizzando i metodi descritti nel blog di Rick Strahl allo http://www.west-wind.com/weblog/posts/324917.aspx (la versione "full fat"). Il debugger salta nel servizio WCF bene (quindi il mio jQuery/JSON viene compreso) e ottiene l'IClient e lo restituisce. Tuttavia, quando restituisco la risposta, ottengo vari errori inutili. Gli errori che sto recuperando non significano molto.

Sto usando POST.

Ho ragione di utilizzare un'interfaccia invece di un oggetto concreto? Come entra nel servizio WCF, sembra essere la codifica del risultato che sta fallendo.

Qualcuno ha qualche idea?

risposta

10

A prima vista ci sono tre problemi con il tuo codice:

1: è necessario utilizzare il ServiceKnownTypeAttribute per specificare i tipi conosciuti quando si espone solo i tipi di base nei vostri contratti di gestione:

[ServiceContract(Namespace = "yyyWCF")]  
public interface IClientBroker 
{ 
    [OperationContract] 
    [ServiceKnownType(typeof(Client))] 
    [WebInvoke(
     Method="GET", 
     BodyStyle=WebMessageBodyStyle.WrappedRequest, 
     ResponseFormat=WebMessageFormat.Json)] 
    IClient GetClientJson(int clientId); 

} 

2: Si dovrebbe usare WebMessageBodyStyle.WrappedRequest invece di WebMessageBodyStyle.Wrapped perché quest'ultimo non è compatibile con WebScriptServiceHostFactory.

3: IMHO usando method = "get" sarebbe più riposante per un metodo chiamato GetClientJson di method = "post"

Un altro consiglio che potrebbe dare quando si lavora con i servizi WCF è quello di utilizzare SvcTraceViewer.exe in bundle con Visual Studio. È un ottimo strumento per scopi di debug. Tutto ciò che serve è quello di aggiungere la seguente sezione al vostro app/web.config:

<system.diagnostics> 
    <sources> 
     <source name="System.ServiceModel" 
       switchValue="Information, ActivityTracing" 
       propagateActivity="true"> 
     <listeners> 
      <add name="sdt" 
       type="System.Diagnostics.XmlWriterTraceListener" 
       initializeData= "WcfDetailTrace.e2e" /> 
     </listeners> 
     </source> 
    </sources> 
    </system.diagnostics> 

quindi richiamare il metodo web e file di WcfDetailTrace.e2e saranno generati nella directory principale del sito web. Successivamente apri questo file con SvcTraceViewer.exe e vedrai molte informazioni utili.Per esempio si potrebbe dire:

Impossibile serializzare parametro di tipo 'MyNamespace.Client' (per il funzionamento 'GetClientJson', contratto 'IClientBroker'), perché non è il tipo esatto 'MyNamespace.IClient' in la firma del metodo e non si trova nella collezione di tipi noti . Al fine di serializzare il parametro , aggiungere il tipo alla raccolta dei tipi noti per l'operazione utilizzando ServiceKnownTypeAttribute.

Naturalmente non dovresti dimenticare di commentare questa sezione prima di andare in produzione o potresti finire con dei file piuttosto grandi.

+0

Grazie a Darin, si scopre che il mio problema è con la serializzazione JSON degli oggetti Entity Framework (bloggato: http://tinyurl.com/cc4k37). Ma il tuo suggerimento su SvcTraceViewer è stato inestimabile nel ricordarmi di questo grande strumento e anche di individuare l'eccezione. Inoltre: concordato su REST per alcuni metodi, solo non questo 1! –

2

Sono sicuro al 99% che non è possibile restituire un'interfaccia. Non penso che le interfacce siano serializzabili.

check-out questa thread

+0

Grazie Mike, hai davvero ragione. Così tanto per la mia bella API basata su interfaccia, eh ?! Ho declassato la mia interfaccia WCF in stringhe JSON, portando la serializzazione "in house". –