2009-03-17 6 views
10

Je suis en train de lutter pour obtenir ce moment magique lorsque le WCF est bien configuré et que jQuery structure bien ses requêtes/compréhension des réponses.JQuery/WCF sans ASP.NET AJAX:

J'ai un service:

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

Cela a été recommandé par l'homme Rick Strahl pour éviter d'avoir à définir les comportements au sein Web.config.

Mon interface pour le service WCF se trouve dans un autre ensemble:

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 de service concret est:

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

Mon iClient est une classe Entity Framework ainsi est décorée avec des attributs DataContract/de DataMember de manière appropriée.

J'essaie d'appeler mon service WCF en utilisant les méthodes décrites sur le blog de Rick Strahl au http://www.west-wind.com/weblog/posts/324917.aspx (la version «complète»). Le débogueur saute dans le service WCF (donc mon jQuery/JSON est compris) et obtient l'IClient et le renvoie. Cependant, quand je retourne la réponse, j'obtiens plusieurs erreurs inutiles. Les erreurs que je reçois ne signifient pas grand-chose.

J'utilise POST.

Ai-je raison d'utiliser une interface au lieu d'un objet concret? Comme il arrive dans le service WCF, il semble que ce soit l'encodage du résultat qui échoue.

Quelqu'un a-t-il des idées?

Répondre

10

À première vue, il y a trois problèmes avec votre code:

1: vous devez utiliser le ServiceKnownTypeAttribute pour spécifier les types connus lors de l'exposition que des types de base dans vos contrats d'exploitation:

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

} 

2: Vous devez utiliser WebMessageBodyStyle.WrappedRequest au lieu de WebMessageBodyStyle.Wrapped parce que ce dernier n'est pas compatible avec WebScriptServiceHostFactory.

3: à mon humble avis en utilisant la méthode « GET » serait plus RESTful pour une méthode appelée GetClientJson que la méthode = « POST »

Un autre conseil que je pourrais vous donner lorsque vous travaillez avec les services WCF est d'utiliser SvcTraceViewer.exe fourni avec Visual Studio. C'est un excellent outil pour le débogage. Tout ce que vous avez besoin est d'ajouter la section suivante à votre application/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> 

Puis invoquez la méthode Web et le fichier WcfDetailTrace.e2e sera généré dans votre site web répertoire racine. Ensuite, ouvrez ce fichier avec SvcTraceViewer.exe et vous verrez beaucoup d'informations utiles.Par exemple, il pourrait dire:

Impossible de sérialiser paramètre de type 'MyNamespace.Client' (pour le fonctionnement 'GetClientJson', contrat 'IClientBroker') parce qu'il est pas le type exact 'MyNamespace.IClient' dans la signature de la méthode et n'est pas dans la collection de types connus . Pour sérialiser le paramètre, ajoutez le type à la collection de types connus pour l'opération en utilisant ServiceKnownTypeAttribute.

Bien sûr, vous ne faut pas oublier de commenter cette section avant d'entrer dans la production ou vous pourriez vous retrouver avec des fichiers assez gros.

+0

Merci Darin, Il s'avère que mon problème est avec JSON sérialisation des objets Entity Framework (blogged: http://tinyurl.com/cc4k37). Mais votre conseil à propos de SvcTraceViewer était inestimable en me rappelant cet excellent outil et en repérant l'exception. Aussi: D'accord sur REST pour certaines méthodes, mais pas cette 1! –

2

Je suis sûr à 99% que vous ne pouvez pas retourner une interface. Je ne pense pas que les interfaces sont sérialisables.

vérifier cette thread

+0

Merci Mike, tu as bien raison. Voilà pour ma belle interface API, hein ?! J'ai rétrogradé mon interface WCF vers des chaînes JSON, ce qui a amené la sérialisation "en interne". –