33

Ho avuto una breve domanda riguardante il datacontractorerializer. Forse è più una questione di flusso. Ho trovato un pezzo di codice che scrive l'xml in un filestream. Fondamentalmente non voglio il file e ho solo bisogno dell'output della stringa.DataContractSerializer - Come posso inviare l'xml a una stringa (a differenza di un file)

public static string DataContractSerializeObject<T>(T objectToSerialize) 
{ 
    var fs = new FileStream("test.xml", FileMode.OpenOrCreate); 
    var serializer = new DataContractSerializer(typeof(T)); 
    serializer.WriteObject(fs, objectToSerialize); 
    fs.Close(); 
    return fs.ToString(); 
} 

fs.ToString() non è ovviamente quello che sto cercando. Quale stream o scrittore etc, posso usare solo per restituire la stringa corretta e non creare un file? Ho dato un'occhiata all'XML creato dal filestream ed è esattamente quello che sto cercando. XmlSerializer ha scritto l'XML un po 'strano e in questo caso preferisco l'output di DataContractSerializer. Qualcuno può indicarmi la giusta direzione?

risposta

60

Qualcosa di simile - mettere l'output in un MemoryStream e poi leggere che nel lontano:

public static string DataContractSerializeObject<T>(T objectToSerialize) 
{ 
    using(MemoryStream memStm = new MemoryStream()) 
    { 
     var serializer = new DataContractSerializer(typeof(T)); 
     serializer.WriteObject(memStm, objectToSerialize); 

     memStm.Seek(0, SeekOrigin.Begin); 

     using(var streamReader = new StreamReader(memStm)) 
     { 
      string result = streamReader.ReadToEnd(); 
      return result; 
     } 
    } 
} 
+2

Looks come te inter cambiato il parametro, dovrebbe essere memStm.Seek (0, SeekOrigin.Begin); – xar

+0

@xar: sì, hai assolutamente ragione - grazie per aver individuato quell'errore - l'ho risolto ora –

+0

Questa soluzione codifica inutilmente da/per utf8. –

22

Grazie a @ xr280xr per aver ricordato mia disposizione StringWriter dimenticato nella prima stesura.

/// <summary> 
/// Converts this instance to XML. 
/// </summary> 
/// <returns>XML representing this instance.</returns> 
public string ToXml() 
{ 
    var serializer = new DataContractSerializer(this.GetType()); 
    using (var output = new StringWriter()) 
    using (var writer = new XmlTextWriter(output) { Formatting = Formatting.Indented }) 
    { 
     serializer.WriteObject(writer, this); 
     return output.GetStringBuilder().ToString(); 
    } 
} 
+1

Anche lo StringWriter deve essere smaltito. – xr280xr

+5

Gli utilizzi impilati fanno proprio questo. – StingyJack

+0

Questo sarebbe anche un ottimo metodo di estensione per DataContractSerializer (e analogamente per XmlSerializer). 'public static string WriteObjectToString (questo serializzatore DataContractSerializer, object obj) {...}' – JamesFaix

18

e ancora più facile:

var serializer = new DataContractSerializer(typeof(T)); 
var sb = new StringBuilder(); 
using (var writer = XmlWriter.Create(sb)) 
{ 
    serializer.WriteObject(writer, objectToSerialize); 
    writer.Flush(); 
    return sb.ToString(); 
} 
2

Suggerisco che combina i metodi fornite dal Pat e marc_s:

public static string DataContractSerializeObject<T>(T objectToSerialize) 
{ 
    using (var output = new StringWriter()) 
    using (var writer = new XmlTextWriter(output) {Formatting = Formatting.Indented}) 
    { 
     new DataContractSerializer(typeof (T)).WriteObject(writer, objectToSerialize); 
     return output.GetStringBuilder().ToString(); 
    } 
} 
+0

Questo è il metodo di Pat con la firma del metodo marc_s. – HappyNomad

0

una variante della risposta @ di root:

var serializer = new DataContractSerializer(typeof(T)); 
var sb = new StringBuilder(); 
using (var writer = XmlWriter.Create(sb)) 
{ 
    serializer.WriteObject(writer, objectToSerialize); 
} 

return sb.ToString(); 
Problemi correlati