2017-03-11 3 views
0

J'essaie de consommer XML à partir d'un appel WebInvoke POST. La classe principale qui reflète la structure XML et XML lui-même sont les suivantes:CollectionDataContract ne reconnaît pas DataContract

XML:

<GraphicArea> 
    <AnimationID>String content</AnimationID> 
    <AutoRetract>true</AutoRetract> 
    <ClientID>2147483647</ClientID> 
    <Description>String content</Description> 
    <GraphicDetails> 
    <GraphicDetail xmlns="http://schemas.datacontract.org/2004/07/fogREST"> 
     <GraphicID>String content</GraphicID> 
     <PropFileDescription>String content</PropFileDescription> 
     <PropFileID>String content</PropFileID> 
     <PropName>String content</PropName> 
     <PropValue>String content</PropValue> 
    </GraphicDetail> 
    <GraphicDetail xmlns="http://schemas.datacontract.org/2004/07/fogREST"> 
     <GraphicID>String content</GraphicID> 
     <PropFileDescription>String content</PropFileDescription> 
     <PropFileID>String content</PropFileID> 
     <PropName>String content</PropName> 
     <PropValue>String content</PropValue> 
    </GraphicDetail> 
    </GraphicDetails> 
    <GraphicSubTypeID>String content</GraphicSubTypeID> 
    <GraphicTypeID>String content</GraphicTypeID> 
    <GraphicTypeTemplateID>String content</GraphicTypeTemplateID> 
    <OffsetX>2147483647</OffsetX> 
    <OffsetY>2147483647</OffsetY> 
    <OffsetZ>2147483647</OffsetZ> 
    <TimeCodeIn>String content</TimeCodeIn> 
    <TimeCodeOut>String content</TimeCodeOut> 
    <UserID>2147483647</UserID> 
</GraphicArea> 

DataContract:

[DataContract(Name = "GraphicArea", Namespace = "")] 
public class GraphicArea 
{ 
    [DataMember(Name = "ClientID")] 
    public virtual int ClientID 
    { 
     get; 
     set; 
    } 
    [DataMember(Name = "AnimationID")] 
    public virtual string AnimationID 
    { 
     get; 
     set; 
    } 
    [DataMember(Name = "GraphicTypeID")] 
    public virtual string GraphicTypeID 
    { 
     get; 
     set; 
    } 
    [DataMember(Name = "GraphicSubTypeID")] 
    public virtual string GraphicSubTypeID 
    { 
     get; 
     set; 
    } 
    [DataMember(Name = "GraphicTypeTemplateID")] 
    public virtual string GraphicTypeTemplateID 
    { 
     get; 
     set; 
    } 
    [DataMember(Name = "TimeCodeIn")] 
    public virtual string TimeCodeIn 
    { 
     get; 
     set; 
    } 
    [DataMember(Name = "TimeCodeOut")] 
    public virtual string TimeCodeOut 
    { 
     get; 
     set; 
    } 
    [DataMember(Name = "AutoRetract")] 
    public virtual bool AutoRetract 
    { 
     get; 
     set; 
    } 
    [DataMember(Name = "Description")] 
    public virtual string Description 
    { 
     get; 
     set; 
    } 
    [DataMember(Name = "UserID")] 
    public virtual int UserID 
    { 
     get; 
     set; 
    } 

    [DataMember(Name = "GraphicDetails")] 
    public GraphicDetailsCollection GraphicDetails 
    { 
     get; 
     set; 
    } 

    [DataMember(Name = "OffsetX")] 
    public virtual int OffsetX 
    { 
     get; 
     set; 
    } 
    [DataMember(Name = "OffsetY")] 
    public virtual int OffsetY 
    { 
     get; 
     set; 
    } 
    [DataMember(Name = "OffsetZ")] 
    public virtual int OffsetZ 
    { 
     get; 
     set; 
    } 
} 

Comme vous pouvez le voir, j'ai un CollectionDataContract appelé GraphicDetailsCollection qui est structuré comme vous voyez ci-dessous:

[CollectionDataContract] 
public class GraphicDetailsCollection : List<GraphicDetail> 
{ 

} 

La collection elle-même est très simple et fait référence à la DataContract:

[DataContract] 
public class GraphicDetail 
{ 
    [DataMember(IsRequired = false)] 
    public string GraphicID; 

    [DataMember(IsRequired = false)] 
    public string PropName; 

    [DataMember(IsRequired = false)] 
    public string PropValue; 

    [DataMember(IsRequired = false)] 
    public string PropFileID; 

    [DataMember(IsRequired = false)] 
    public string PropFileDescription; 
} 

J'ai cette configuration, car il peut y avoir potentiellement un certain nombre de sections dans les GraphicDetail GraphicDetails. Je peux gérer toutes les données dans l'amende XML à l'exception du contenu GraphicDetail dans GraphicDetails. Le problème que j'ai est que quand je fais des références à contract.GraphicDetails.Count afin de faire une boucle à travers les différents ensembles de GraphicDetail, je vois que contract.GraphicDetails.Count = 0 et tous ses DataMembers = Null qui n'est pas vrai. Est-ce que quelqu'un peut expliquer pourquoi cela pourrait être? Je suis un peu nouveau chez DataContracts et j'ai l'impression d'être très proche ou d'avoir travaillé dans un coin sans vraiment comprendre les collections et les contrats et avoir besoin d'une approche différente.

Toutes les pensées seraient utiles, merci!

Répondre

0

Dans le fichier XML illustré, le <GraphicDetail> a un default namespacexmlns="http://schemas.datacontract.org/2004/07/fogREST". Ainsi cet élément et tous ses éléments enfants sont dans cet espace de noms tant qu'ils n'ont pas de préfixe d'espace de nommage explicite (ce qu'ils font). Vos contrats de données doivent refléter ce fait:

[CollectionDataContract(Namespace = "http://schemas.datacontract.org/2004/07/fogREST")] // All GraphicDetail child XML elements are to be in the indicated namespace 
public class GraphicDetailsCollection : List<GraphicDetail> 
{ 
} 

[DataContract(Namespace = "http://schemas.datacontract.org/2004/07/fogREST")] // All data member child XML elements are to be in the indicated namespace 
public class GraphicDetail 
{ 
    [DataMember(IsRequired = false)] 
    public string GraphicID; 

    [DataMember(IsRequired = false)] 
    public string PropName; 

    [DataMember(IsRequired = false)] 
    public string PropValue; 

    [DataMember(IsRequired = false)] 
    public string PropFileID; 

    [DataMember(IsRequired = false)] 
    public string PropFileDescription; 
} 
+0

Salut dbc, Tout d'abord, merci pour votre aide! J'ai réussi à faire fonctionner ceci mais j'ai maintenant un problème où j'ai un seul DataMember qui peut avoir ou non une valeur nulle. Dans ma configuration actuelle, le DataContractSerializer renverra un champ s'il n'y a pas de valeur pour PropFileID mais ce que je veux vraiment, c'est que cet élément soit complètement ignoré (non généré). Y a-t-il un moyen d'y parvenir? EmitDefaultValue = false semble être sur la bonne voie mais ne fonctionne que sur la sérialisation et non sur la désérialisation. –

+0

@ChrisHarvey - ['DataMemberAttribute.EmitDefaultValue'] (https://msdn.microsoft.com/fr-fr/library/system.runtime.serialization.datamemberattribute.emitdefaultvalue (v = vs.110) .aspx) devrait fonctionner. Mais vous avez écrit, [il] semble être sur la bonne voie, mais ne fonctionne que sur la sérialisation et non sur la désérialisation. * Dans ce cas, je suggère de poser une deuxième question avec un [mcve] montrant ce qui ne fonctionne pas. – dbc

+0

Salut dbc, j'ai créé une nouvelle question pour développer davantage sur le problème. Cela vous dérangerait-il de le vérifier? http://stackoverflow.com/questions/42800889/datacontractserializer-not-allowing-dynamic-datamembers –