Serializar un objeto a una cadena
Tengo el siguiente método para guardar un Objeto en un archivo:
// Save an object out to the disk
public static void SerializeObject<T>(this T toSerialize, String filename)
{
XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
TextWriter textWriter = new StreamWriter(filename);
xmlSerializer.Serialize(textWriter, toSerialize);
textWriter.Close();
}
Confieso que no lo escribí (solo lo convertí a un método de extensión que tomaba un parámetro de tipo).
Ahora necesito que me devuelva el xml como una cadena (en lugar de guardarlo en un archivo). Lo estoy investigando, pero aún no lo he descubierto.
Pensé que esto podría ser muy fácil para alguien familiarizado con estos objetos. Si no, lo resolveré eventualmente.
Utilice a StringWriter
en lugar de a StreamWriter
:
public static string SerializeObject<T>(this T toSerialize)
{
XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
using(StringWriter textWriter = new StringWriter())
{
xmlSerializer.Serialize(textWriter, toSerialize);
return textWriter.ToString();
}
}
Tenga en cuenta que es importante usarlo toSerialize.GetType()
en lugar de typeof(T)
en el constructor XmlSerializer: si usa el primero, el código cubre todas las subclases posibles T
(que son válidas para el método), mientras que el uso del último fallará al pasar un tipo derivado de T
. Aquí hay un enlace con un código de ejemplo que motiva esta declaración, con XmlSerializer
el lanzamiento de un Exception
cuándo typeof(T)
, porque se pasa una instancia de un tipo derivado a un método que llama a SerializeObject que está definido en la clase base del tipo derivado: http://ideone .com/1Z5J1 .
Además, Ideone usa Mono para ejecutar código; el real que Exception
obtendrías usando el tiempo de ejecución de Microsoft .NET es diferente Message
al que se muestra en Ideone, pero falla de todos modos.
Serializar y deserializar XML/JSON ( SerializationHelper.cs
) (puede utilizar el paquete Newtonsoft.Json Nuget para la serialización JSON):
using Newtonsoft.Json;
using System.IO;
using System.Xml.Serialization;
namespace MyProject.Helpers
{
public static class SerializationHelper
{
public static T DeserializeXml<T>(this string toDeserialize)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
using (StringReader textReader = new StringReader(toDeserialize))
{
return (T)xmlSerializer.Deserialize(textReader);
}
}
public static string SerializeXml<T>(this T toSerialize)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
using (StringWriter textWriter = new StringWriter())
{
xmlSerializer.Serialize(textWriter, toSerialize);
return textWriter.ToString();
}
}
public static T DeserializeJson<T>(this string toDeserialize)
{
return JsonConvert.DeserializeObject<T>(toDeserialize);
}
public static string SerializeJson<T>(this T toSerialize)
{
return JsonConvert.SerializeObject(toSerialize);
}
}
}
Alternativamente, puede usar el paquete System.Text.Json Nuget en su lugar para la serialización Json:
using System.Text.Json;
...
public static T DeserializeJson<T>(this string toDeserialize, JsonSerializerOptions options = null)
{
return JsonSerializer.Deserialize<T>(toDeserialize, options);
}
public static string SerializeJson<T>(this T toSerialize, JsonSerializerOptions options = null)
{
return JsonSerializer.Serialize<T>(toSerialize, options);
}
Sé que esto no es realmente una respuesta a la pregunta, pero según la cantidad de votos para la pregunta y la respuesta aceptada, sospecho que la gente en realidad está usando el código para serializar un objeto en una cadena.
El uso de la serialización XML agrega basura de texto adicional innecesaria a la salida.
Para la siguiente clase
public class UserData
{
public int UserId { get; set; }
}
genera
<?xml version="1.0" encoding="utf-16"?>
<UserData xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<UserId>0</UserId>
</UserData>
Una mejor solución es utilizar la serialización JSON (una de las mejores es Json.NET ). Para serializar un objeto:
var userData = new UserData {UserId = 0};
var userDataString = JsonConvert.SerializeObject(userData);
Para deserializar un objeto:
var userData = JsonConvert.DeserializeObject<UserData>(userDataString);
La cadena JSON serializada tendría este aspecto:
{"UserId":0}