2011-12-21 13 views
5

Come si serializza un elenco senza l'elemento esterno utilizzando il serializzatore contratto dati? Sto usando .Net 3.5. Ho una classe che contiene un elenco, tra le altre cose, che desidero serializzare senza l'elemento esterno per essere compatibile con il XSD pertinente:- Come omettere l'elemento esterno di una raccolta

[DataContract(Name="MyClass")] 
public class MyClass 
{ 
... 
[DataMember(Name="Parameters")] 
public List<Parameter> Parameters; 
... 
} 

[DataContract(Name="Parameter")] 
public struct Parameter 
{ 
    [DataMember(Name="ValueName")]string ValueName; 
    [DataMember(Name="Value")]int Value; 
    public Parameter(string ValueName, int Value) 
    { 
     this.ValueName = ValueName; 
     this.Value = Value;    
    } 
} 

Quanto sopra serializza come (supponendo un solo parametro nella lista) :

<MyClass> 
    <Parameters> 
     <Parameter> 
      <ValueName></ValueName> 
      <Value></Value> 
     </Parameter> 
    </Parameters> 
</MyClass> 

Vorrei serializzare come segue:

<MyClass> 
     <Parameter> 
      <ValueName></ValueName> 
      <Value></Value> 
     </Parameter> 
</MyClass> 

Utilizzando il XmlSerializer posso farlo applicando la [XmlElement] alla lista:

[XmlElement ("Parameter")] 
public List<Parameter> Parameters; 

Comunque io non voglio usare il XmlSerializer perché la mia classe ha alcune proprietà che non sono la serializzazione amichevole e speravo di affrontare coloro che utilizzano la famiglia [OnSerializing] di attributi.

Grazie.

+0

Non avete molto controllo su un messaggio formattazione con DataContracts. Potrebbe essere necessario utilizzare MessageContract - vedere http://msdn.microsoft.com/en-us/library/ms730255.aspx – StuartLC

risposta

4

Il serializzatore DataContract non consente questo livello di controllo sull'XML risultante, per ottenere ciò è necessario utilizzare lo XmlSerializer.

+0

OK, grazie. Ogni volta che cerco qualcosa e non riesco a trovarlo, di solito è perché non può essere fatto o è così stupido che nessun altro ha pensato di farlo. Grazie per aver confermato il precedente ;-) – chrisj

+0

Come posso usare XmlSerializer per controllare il risultato? – natenho

+0

@natenho vedere la domanda, l'OP ha già una soluzione per quello in fondo alla domanda. –

0

Il seguente funziona utilizzando MessageContracts anche se è un 'hack' - attribuisce l'elemento "MyClass" al membro di List ed esclude lo spazio dei nomi wrapper per "MyClass".

[ServiceContract(Namespace="")] 
public interface IService1 
{ 
    [OperationContract] 
    MyClass GetParameters(); 
    // TODO: Add your service operations here 
} 

[DataContract(Namespace="")] 
public class Parameter 
{ 
    [DataMember] 
    public string ValueName 
    { 
     get; 
     set; 
    } 
    [DataMember] 
    public int Value 
    { 
     get; 
     set; 
    } 

    public Parameter(string ValueName, int Value) 
    { 
     this.ValueName = ValueName; 
     this.Value = Value; 
    } 
} 

[MessageContract(IsWrapped = false, WrapperNamespace="")] 
public class MyClass 
{ 
    [MessageBodyMember(Name = "MyClass", Namespace = "")] 
    public List<Parameter> Parameters 
    { 
     get; 
     set; 
    } 
} 
3

Utilizzare un contratto di raccolta dei dati:

[CollectionDataContract(Name = "MyClass", ItemName = "Parameter")] 
    public class ParameterList : List<Parameter> 
    { 

    } 
+0

Non so perché qualcuno ha downvoted questo (forse hanno potuto lasciare un commento sul motivo: ha funzionato per me ed è documentato qui: https://msdn.microsoft.com/en-us/library/system.runtime.serialization. collectiondatacontractattribute (v = vs.90) .aspx –

+0

Suppongo che sia stato downvoted perché causerà comunque un elemento esterno con ripetizioni di elementi figlio . La domanda richiede in particolare un modo per sbarazzarsi dell'elemento esterno. – Gruff

+0

La domanda non ha chiesto di sbarazzarsi dell'elemento esterno (MyClass) chiede di sbarazzarsi di quello sotto (Parametri) ... che è esattamente ciò che fa questo attributo! –

Problemi correlati