2010-07-01 8 views
0

J'implémente une API lo-REST et je cherche à retourner XML ou JSON. Construire dans .NET WCF.Types complexes complexes WCF wrap pour REST

J'aime la conception des deux API Flickr et Last FM qui enveloppent leurs types complexes variables dans une simple réponse ala:

<lfm status="ok"> 
    <user> 
    <name>RJ</name> 
    <realname>Richard Jones </realname> 
    <country>UK</country> 
    <age>27</age> 
    </user> 
</lfm> 

ou

<lfm status="ok"> 
    <track> 
    <name>Best track ever</name> 
    <album>Thriller</album> 
    </user> 
</lfm> 

ou

<lfm status="fail"> 
    ... error details 
</lfm> 

La sérialisation des types complexes est simple comme vous pouvez vous y attendre (en utilisant DataContract, DataMember, etc.). Mais l'emballer dans une sorte de réponse personnalisée me fait trébucher à cause des types complexes variables qui peuvent être contenus à l'intérieur. Donner la réponse d'un membre objet de type qui est rempli par le type complexe ne sérialise pas:

[DataContract] 
public class Response 
{ 
    public enum ResponseStatus 
    { 
     ok, 
     fail 
    } 

    [DataMember] 
    public ResponseStatus Status { get; set; } 

    [DataMember] 
    public object Data { get; set; } 

} 

Toutes les idées ou aide est grandement appréciée.

Un grand merci, Alex

EDIT: Tim Roberts offre une solution intéressante même si elle ne serialise pas bien. Une option consiste à spécifier tous les types complexes potentiels en tant que propriétés avec [DataMember (EmitDefaultValue = false)] afin que les valeurs NULL ne soient pas sérialisées. Je ne suis pas sûr que ce soit la meilleure solution.

Répondre

1

Vous pouvez définir une hiérarchie de classes pour vos Data types au sein Response:

par exemple,

[DataContract] 
public abstract class Data 
{ } 

[DataContract] 
public class FooData : Data 
{ } 

[DataContract] 
public class BarData : Data 
{ } 

indiquent alors les types connus sur la classe Response:

[DataContract] 
[KnownType(typeof(FooData))] 
[KnownType(typeof(BarData))] 
public class Response 
{ 
    public enum ResponseStatus 
    { 
     ok, 
     fail 
    } 

    [DataMember] 
    public ResponseStatus Status { get; set; } 

    [DataMember] 
    public Data Data { get; set; } 
} 
+0

En fait, il Il est plus logique de mettre l'attribut [KnownType] sur la classe Data. –

+0

C'est presque là. Le problème est de savoir comment il se sérialisait. Vous vous retrouvez avec un nœud comme au lieu de . – Maleks