2017-03-11 2 views
0

Ich versuche XML von einem WebInvoke POST-Aufruf zu konsumieren. Die Hauptklasse, die die XML-Struktur und die XML selbst spiegelt sich wie folgt dar:CollectionDataContract erkennt DataContract nicht

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

Wie Sie sehen, ich habe ein CollectionDataContract GraphicDetailsCollection genannt, die ist strukturiert wie Sie unten sehen:

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

} 

Die Sammlung selbst ist und sehr einfach bezieht sich auf die 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; 
} 

ich dieses Setup haben, weil es kann möglicherweise eine beliebige Anzahl von graphic Abschnitte innerhalb GraphicDetails. Ich kann alle Daten innerhalb des XML-Ordners verarbeiten, mit Ausnahme des GraphicDetail-Inhalts in GraphicDetails. Das Problem, das ich habe, ist, dass, wenn ich Verweise auf contract.GraphicDetails.Count mache, um durch die verschiedenen Sätze von GraphicDetail durchzulaufen, ich sehe, dass contract.GraphicDetails.Count = 0 und alle seine DataMembers = Null, die nicht wahr ist.

Kann jemand erklären, warum das sein könnte? Ich bin etwas neu in DataContracts und ich habe das Gefühl, dass ich entweder sehr nah dran bin oder mich in eine Ecke gearbeitet habe, ohne Collections und Contracts vollständig zu verstehen, und einen anderen Ansatz brauche.

Alle Gedanken wären hilfreich, danke!

Antwort

0

In der gezeigten XML-Datei hat die <GraphicDetail> eine default namespacexmlns="http://schemas.datacontract.org/2004/07/fogREST". Daher befinden sich dieses Element und alle untergeordneten Elemente in diesem Namespace, solange ihnen kein explizites Namespacepräfix fehlt (was sie tun). Ihre Daten Verträge müssen diese Tatsache widerspiegeln:

[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

Hallo dbc, Zunächst einmal, vielen Dank für Ihre Hilfe! Ich konnte dies zum Laufen bringen, aber ich habe jetzt ein Problem, bei dem ich ein einzelnes DataMember habe, das einen Nullwert haben kann oder auch nicht. In meinem aktuellen Setup, der DataContractSerializer wird ein Feld zurückgeben, wenn es keinen Wert für PropFileID gibt, aber was ich wirklich will, ist dieses Element vollständig ignoriert (nicht generiert). Gibt es einen Weg, dies zu erreichen? EmitDefaultValue = false scheint auf der richtigen Spur zu sein, funktioniert aber nur bei Serialisierung und nicht bei Deserialisierung. –

+0

@ChrisHarvey - ['DataMemberAttribute.EmitDefaultValue'] (https://msdn.microsoft.com/en-us/library/system.runtime.serialization.datamberattribute.emitdefaultvalue (v = vs.110) .aspx) sollte funktionieren. Aber Sie haben geschrieben, * [es] scheint auf dem richtigen Weg zu sein, funktioniert aber nur bei der Serialisierung und nicht bei der Deserialisierung. * In diesem Fall würde ich vorschlagen, eine zweite Frage mit einem vollständigen [mcve] zu stellen, was nicht funktioniert. – dbc

+0

Hallo dbc, ich habe eine neue Frage erstellt, um das Problem weiter zu vertiefen. Würde es dir etwas ausmachen, es auszuprobieren? http://stackoverflow.com/questions/42800889/datacontractserializer-not-allowing-dynamic-datamembers –