33

Tuve una pregunta rápida sobre el datacontraerializer. Tal vez es más una pregunta de flujo. Encontré un fragmento de código que escribe el xml en una cadena de archivos. Básicamente no quiero el archivo y solo necesito el resultado de la cadena.DataContractSerializer: cómo puedo enviar el xml a una cadena (a diferencia de un archivo)

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() no es, obviamente, lo que estoy buscando. ¿Qué secuencia o escritor, etc., puedo usar solo para devolver la cadena correcta y no crear un archivo? Miré el XML creado por filestream y es exactamente lo que estoy buscando. El XmlSerializer escribió el XML un poco extraño y prefiero el resultado del DataContractSerializer en este caso. ¿Alguien puede señalarme en la dirección correcta?

Respuesta

60

Algo como esto - ponga su salida en un MemoryStream y luego leer que allá por:

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

miradas como tú inter cambió el parámetro, debería ser memStm.Seek (0, SeekOrigin.Begin); – xar

+0

@xar: sí, tiene toda la razón, gracias por detectar ese error. Lo arreglé ahora. –

+0

Esta solución codifica innecesariamente a/desde utf8. –

22

Gracias a @ xr280xr por señalar mi disposición StringWriter olvidado en el primer borrador.

/// <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

Su StringWriter debe eliminarse también. – xr280xr

+5

Los usos apilados hacen precisamente eso. – StingyJack

+0

Esto también sería un excelente método de extensión para DataContractSerializer (y análogamente para XmlSerializer). 'cadena estática pública WriteObjectToString (este serializador DataContractSerializer, object obj) {...}' – JamesFaix

18

Y aún más fácil:

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

Sugiero que combina los métodos dados por Pat y 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

Este es el método de Pat con la firma del método marc_s. – HappyNomad

0

una variante de respuesta de @ root:

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

return sb.ToString(); 
Cuestiones relacionadas