serializacion - serializar xml c#
Serializar un objeto a la cadena (10)
Nota de seguridad del código
Con respecto a la respuesta aceptada , es importante usar toSerialize.GetType()
lugar de typeof(T)
en el constructor XmlSerializer
: si usa la primera, el código cubre todos los escenarios posibles, mientras que la última falla a veces.
Aquí hay un enlace con un código de ejemplo que motiva esta declaración, con XmlSerializer
lanzando una excepción cuando se usa typeof(T)
, porque pasa una instancia de un tipo derivado a un método que llama a SerializeObject<T>()
que se define en la clase base del tipo derivado: http://ideone.com/1Z5J1 . Tenga en cuenta que Ideone usa Mono para ejecutar el código: la excepción real que obtendría al utilizar el tiempo de ejecución de Microsoft .NET tiene un Mensaje diferente al que se muestra en Ideone, pero falla de la misma manera.
Para completar la información, publico el ejemplo de código completo aquí para futuras referencias, en caso de que Ideone (donde publiqué el código) no esté disponible en el futuro:
using System;
using System.Xml.Serialization;
using System.IO;
public class Test
{
public static void Main()
{
Sub subInstance = new Sub();
Console.WriteLine(subInstance.TestMethod());
}
public class Super
{
public string TestMethod() {
return this.SerializeObject();
}
}
public class Sub : Super
{
}
}
public static class TestExt {
public static string SerializeObject<T>(this T toSerialize)
{
Console.WriteLine(typeof(T).Name); // PRINTS: "Super", the base/superclass -- Expected output is "Sub" instead
Console.WriteLine(toSerialize.GetType().Name); // PRINTS: "Sub", the derived/subclass
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
StringWriter textWriter = new StringWriter();
// And now...this will throw and Exception!
// Changing new XmlSerializer(typeof(T)) to new XmlSerializer(subInstance.GetType());
// solves the problem
xmlSerializer.Serialize(textWriter, toSerialize);
return textWriter.ToString();
}
}
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 tomó un parámetro de tipo).
Ahora lo necesito para devolverme 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 realmente fácil para alguien familiarizado con estos objetos. Si no, lo resolveré eventualmente.
En algunos casos raros, es posible que desee implementar su propia serialización de cadenas.
Pero probablemente sea una mala idea a menos que sepa lo que está haciendo. (p. ej., serialización para E / S con un archivo por lotes)
Algo así funcionaría (y sería fácil de editar a mano / por lote), pero tenga cuidado de que se realicen más comprobaciones, ya que ese nombre no contiene una nueva línea.
public string name {get;set;}
public int age {get;set;}
Person(string serializedPerson)
{
string[] tmpArray = serializedPerson.Split(''/n'');
if(tmpArray.Length>2 && tmpArray[0].Equals("#")){
this.name=tmpArray[1];
this.age=int.TryParse(tmpArray[2]);
}else{
throw new ArgumentException("Not a valid serialization of a person");
}
}
public string SerializeToString()
{
return "#/n" +
name + "/n" +
age;
}
Mi 2p ...
string Serialise<T>(T serialisableObject)
{
var xmlSerializer = new XmlSerializer(serialisableObject.GetType());
using (var ms = new MemoryStream())
{
using (var xw = XmlWriter.Create(ms,
new XmlWriterSettings()
{
Encoding = new UTF8Encoding(false),
Indent = true,
NewLineOnAttributes = true,
}))
{
xmlSerializer.Serialize(xw,serialisableObject);
return Encoding.UTF8.GetString(ms.ToArray());
}
}
}
No pude usar el método JSONConvert sugerido por xhafan
En .Net 4.5, incluso después de agregar la referencia de ensamblado "System.Web.Extensions", aún no podía acceder a JSONConvert.
Sin embargo, una vez que agrega la referencia, puede obtener la misma cadena impresa usando:
JavaScriptSerializer js = new JavaScriptSerializer();
string jsonstring = js.Serialize(yourClassObject);
Sé que esto no es realmente una respuesta a la pregunta, pero en base al número de votos de la pregunta y la respuesta aceptada, sospecho que las personas realmente están usando el código para serializar un objeto en una cadena.
El uso de la serialización XML agrega desperdicios de texto extra innecesarios a la salida.
Para la siguiente clase
public class UserData
{
public int UserId { get; set; }
}
se 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 se vería así:
{"UserId":0}
Sentí que necesitaba compartir este código manipulado con la respuesta aceptada, ya que no tengo reputación, no puedo hacer comentarios.
using System;
using System.Xml.Serialization;
using System.IO;
namespace ObjectSerialization
{
public static class ObjectSerialization
{
// THIS: (C): https://.com/questions/2434534/serialize-an-object-to-string
/// <summary>
/// A helper to serialize an object to a string containing XML data of the object.
/// </summary>
/// <typeparam name="T">An object to serialize to a XML data string.</typeparam>
/// <param name="toSerialize">A helper method for any type of object to be serialized to a XML data string.</param>
/// <returns>A string containing XML data of the object.</returns>
public static string SerializeObject<T>(this T toSerialize)
{
// create an instance of a XmlSerializer class with the typeof(T)..
XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
// using is necessary with classes which implement the IDisposable interface..
using (StringWriter stringWriter = new StringWriter())
{
// serialize a class to a StringWriter class instance..
xmlSerializer.Serialize(stringWriter, toSerialize); // a base class of the StringWriter instance is TextWriter..
return stringWriter.ToString(); // return the value..
}
}
// THIS: (C): VPKSoft, 2018, https://www.vpksoft.net
/// <summary>
/// Deserializes an object which is saved to an XML data string. If the object has no instance a new object will be constructed if possible.
/// <note type="note">An exception will occur if a null reference is called an no valid constructor of the class is available.</note>
/// </summary>
/// <typeparam name="T">An object to deserialize from a XML data string.</typeparam>
/// <param name="toDeserialize">An object of which XML data to deserialize. If the object is null a a default constructor is called.</param>
/// <param name="xmlData">A string containing a serialized XML data do deserialize.</param>
/// <returns>An object which is deserialized from the XML data string.</returns>
public static T DeserializeObject<T>(this T toDeserialize, string xmlData)
{
// if a null instance of an object called this try to create a "default" instance for it with typeof(T),
// this will throw an exception no useful constructor is found..
object voidInstance = toDeserialize == null ? Activator.CreateInstance(typeof(T)) : toDeserialize;
// create an instance of a XmlSerializer class with the typeof(T)..
XmlSerializer xmlSerializer = new XmlSerializer(voidInstance.GetType());
// construct a StringReader class instance of the given xmlData parameter to be deserialized by the XmlSerializer class instance..
using (StringReader stringReader = new StringReader(xmlData))
{
// return the "new" object deserialized via the XmlSerializer class instance..
return (T)xmlSerializer.Deserialize(stringReader);
}
}
// THIS: (C): VPKSoft, 2018, https://www.vpksoft.net
/// <summary>
/// Deserializes an object which is saved to an XML data string.
/// </summary>
/// <param name="toDeserialize">A type of an object of which XML data to deserialize.</param>
/// <param name="xmlData">A string containing a serialized XML data do deserialize.</param>
/// <returns>An object which is deserialized from the XML data string.</returns>
public static object DeserializeObject(Type toDeserialize, string xmlData)
{
// create an instance of a XmlSerializer class with the given type toDeserialize..
XmlSerializer xmlSerializer = new XmlSerializer(toDeserialize);
// construct a StringReader class instance of the given xmlData parameter to be deserialized by the XmlSerializer class instance..
using (StringReader stringReader = new StringReader(xmlData))
{
// return the "new" object deserialized via the XmlSerializer class instance..
return xmlSerializer.Deserialize(stringReader);
}
}
}
}
Serializar y Deserializar:
public static T Deserialize<T>(this string toDeserialize)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
using(StringReader textReader = new StringReader(toDeserialize))
{
return (T)xmlSerializer.Deserialize(textReader);
}
}
public static string Serialize<T>(this T toSerialize)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
using(StringWriter textWriter = new StringWriter())
{
xmlSerializer.Serialize(textWriter, toSerialize);
return textWriter.ToString();
}
}
Utilice un StringWriter
lugar de un 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 utilizar toSerialize.GetType()
lugar de typeof(T)
en el constructor XmlSerializer: si usa el primero, el código cubre todas las subclases de T
(que son válidas para el método), mientras usa el último fallará al pasar un tipo derivado de T
Aquí hay un enlace con algún código de ejemplo que motiva esta declaración, con XmlSerializer
lanzando una Exception
cuando se usa typeof(T)
, porque 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; La Exception
real que obtendría al usar el tiempo de ejecución de Microsoft .NET tiene un Message
diferente al que se muestra en Ideone, pero falla de igual manera.
[VB]
Public Function XmlSerializeObject(ByVal obj As Object) As String
Dim xmlStr As String = String.Empty
Dim settings As New XmlWriterSettings()
settings.Indent = False
settings.OmitXmlDeclaration = True
settings.NewLineChars = String.Empty
settings.NewLineHandling = NewLineHandling.None
Using stringWriter As New StringWriter()
Using xmlWriter__1 As XmlWriter = XmlWriter.Create(stringWriter, settings)
Dim serializer As New XmlSerializer(obj.[GetType]())
serializer.Serialize(xmlWriter__1, obj)
xmlStr = stringWriter.ToString()
xmlWriter__1.Close()
End Using
stringWriter.Close()
End Using
Return xmlStr.ToString
End Function
Public Function XmlDeserializeObject(ByVal data As [String], ByVal objType As Type) As Object
Dim xmlSer As New System.Xml.Serialization.XmlSerializer(objType)
Dim reader As TextReader = New StringReader(data)
Dim obj As New Object
obj = DirectCast(xmlSer.Deserialize(reader), Object)
Return obj
End Function
[DO#]
public string XmlSerializeObject(object obj)
{
string xmlStr = String.Empty;
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = false;
settings.OmitXmlDeclaration = true;
settings.NewLineChars = String.Empty;
settings.NewLineHandling = NewLineHandling.None;
using (StringWriter stringWriter = new StringWriter())
{
using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter, settings))
{
XmlSerializer serializer = new XmlSerializer( obj.GetType());
serializer.Serialize(xmlWriter, obj);
xmlStr = stringWriter.ToString();
xmlWriter.Close();
}
}
return xmlStr.ToString();
}
public object XmlDeserializeObject(string data, Type objType)
{
XmlSerializer xmlSer = new XmlSerializer(objType);
StringReader reader = new StringReader(data);
object obj = new object();
obj = (object)(xmlSer.Deserialize(reader));
return obj;
}
public static string SerializeObject<T>(T objectToSerialize)
{
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
MemoryStream memStr = new MemoryStream();
try
{
bf.Serialize(memStr, objectToSerialize);
memStr.Position = 0;
return Convert.ToBase64String(memStr.ToArray());
}
finally
{
memStr.Close();
}
}
public static T DerializeObject<T>(string objectToDerialize)
{
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
byte[] byteArray = Convert.FromBase64String(objectToDerialize);
MemoryStream memStr = new MemoryStream(byteArray);
try
{
return (T)bf.Deserialize(memStr);
}
finally
{
memStr.Close();
}
}