2009-10-14 10 views
7

Je veux retourner un type anonyme sur WCF. Est-ce possible?Types WCF et anonymes

+0

Comment le client sait quel sera le type? –

+0

Ceci est une chose _wrong_ à faire, même si vous utilisez un contrat non typé –

+2

Voici quelques idées pour lesquelles quelqu'un aurait besoin de cela. 1. Le client pourrait être Javascript traitant des réponses JSON, n'ayant aucune idée du type de toute façon. 2. On pourrait vouloir faire des demandes 'génériques' à WCF sans avoir à maintenir de nombreux types de réponses. Il est triste de constater que seule la réponse (positive) (@ dave-ward) semble manquer de détails de configuration qui rendent cela possible. – tishma

Répondre

0

Non, ce n'est pas le cas. Vous devrez définir vos types à l'avance.

+0

OK, je comprends. Mais alors si je définis un type - MyObj - et marque ses membres IsRequired = false, comment puis-je créer + envoyer à travers une instance de MyObj avec seulement certains de ses membres? Est-ce possible?? –

+0

Voir les réponses d'Eugene Osovetsky ou de marc_s. L'une ou l'autre route vous aidera. Je dirais que la réponse de marc_s est probablement la meilleure pour votre problème. – Randolpho

3

Vous ne pouvez pas renvoyer un type anonyme de n'importe quelle méthode, pouvez-vous? Alors, pourquoi seriez-vous en mesure de le renvoyer de la WCF?

+0

Je ne comprends pas ce downvote - John a absolument raison, les types anonymes ne peuvent être retournés à partir de n'importe quelle méthode .NET, vous pouvez seulement les utiliser ** dans ** votre méthode actuelle. Pourquoi un downvote pour une réponse qui est 100% correcte ...... –

+0

Pas entièrement. Vous pouvez renvoyer des types anonymes en tant qu '"objet", ce qui fonctionne parfaitement avec l'API Web et le sérialiseur JSON. –

+0

Cette question concerne le WCF en général et non l'API Web. En outre, le format JSON inclut les noms de champs. Il peut être sérialisé et désérialisé correctement pour JavaScript. Mais essayez de sérialiser la valeur de chaîne "20" pour la désérialiser en tant que chaîne ou en tant qu'entier. Cela n'a pas d'importance pour Javascript mais probablement pour C#. Faites attention à la façon dont vous définissez "fonctionne très bien". –

4

Vous ne pouvez pas utiliser les types anonymes, mais vous parlez peut-être de WCF et de messages non typés?

Il existe une option dans WCF pour définir un paramètre de type Message (et éventuellement une valeur de retour du même type). C'est juste le message brut qui va à la WCF (et en revient).

Je ne trouve pas beaucoup de bonnes informations là-bas - il y a de la documentation sur MSDN, mais le meilleur que j'ai vu jusqu'ici est l'article de blog de Kurt Claeys WCF : Untyped messages on WCF operations.

Je ne recommanderais pas d'utiliser cette approche - il est beaucoup plus fastidieux de manipuler le contenu du message directement et c'est ce que WCF essaie de nous épargner - mais si vous devez absolument, modifier positivement chaque partie de votre message - Cela semble être le chemin à parcourir.

Marc

+0

Les messages personnalisés sont probablement la voie à suivre pour celui-ci. +1 – Randolpho

1

OK, je comprends. Mais si je un type définis - MyObj - à cet effet et marquer ses membres isRequired = false, comment puis-je créer + envoyer à travers une instance de MyObj avec seulement quelques-uns de ses membres ? Est-ce possible??

Jetez un oeil à [DataMember(EmitDefaultValue=false)]

0

Vous pouvez certainement revenir des types anonymes. Cela fonctionne, par exemple:

public object GetLatestPost() 
{ 
    XDocument feedXML = XDocument.Load("http://feeds.encosia.com/Encosia"); 

    var posts = from feed in feedXML.Descendants("item") 
        select new 
        { 
        Title = feed.Element("title").Value, 
        Link = feed.Element("link").Value, 
        Description = feed.Element("description").Value 
        }; 

    return posts.First(); 
} 

Si vous appelez cette méthode comme la WebMethod de ASMX ScriptService, vous obtiendrez ce JSON de lui:

{"d": 
    {"Title":"Using an iPhone with the Visual Studio development server", 
    "Link":"http://feeds.encosia.com/~r/Encosia/~3/vQoxmC6lOYk/", 
    "Description":" Developing iPhone-optimized portions of an ASP.NET ..."}} 

Vous pouvez utiliser un type de retour de IEnumerable revenir une collection de types anonymes aussi.

+4

Impossible de faire fonctionner ceci dans .NET 4 WCF. Je vais continuer à le pirater .. – vlad259

+0

Des succès ici? Je continue d'obtenir 504 erreur au lieu de la réponse. – tishma

1

On dirait que vous ne pouvez pas le faire avec XML Serializer en raison d'une plainte sur un constructeur sans paramètre, mais cela fonctionne pour le sérialiseur json si vous servez un client ajax comme indiqué par Dave Ward.

0

Vous pouvez utiliser ExpandoObject. Lorsque vous définissez une propriété dans un DTO comme ExpandoObject le client est généré comme Dictionnaire:

contrat DTO

public class TaskDTO 
{ 
    public string Type { get; set; } 
    public ExpandoObject Args { get; set; } 
    public string Id { get; set; } 
    public TaskDTO SuccessTask { get; set; } 
    public TaskDTO FailTask { get; set; } 
    public bool IsFinal { get; set; } 
} 

client

using (var client = new JobServiceClient()) 
{ 
    var task = new TaskDTO 
    { 
     Id = Guid.NewGuid().ToString(), 
     Type = "SendEmailTask", 
     IsFinal = true 
    }; 
    dynamic args = new ExpandoObject(); 
    args.To = "[email protected]"; 
    args.Title = "test job service"; 
    args.Content = "test job service"; 
    task.Args = ((IDictionary<string, object>)args).ToDictionary(i => i.Key, i => i.Value); 
    client.Execute(task); 
} 

service

dynamic args = dto.Args; 
Questions connexes