serialize serializar objeto newtonsoft deserialize deserializar convertir and c# xml-serialization

serializar - serialize json c# newtonsoft



Serializar un objeto a XML (13)

Tengo una clase de C # que he heredado. He "construido" con éxito el objeto. Pero necesito serializar el objeto a XML. ¿Hay una manera fácil de hacerlo?

Parece que la clase se ha configurado para la serialización, pero no estoy seguro de cómo obtener la representación XML. Mi definición de clase se ve así:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.domain.com/test")] [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.domain.com/test", IsNullable = false)] public partial class MyObject { ... }

Esto es lo que pensé que podía hacer, pero no funciona:

MyObject o = new MyObject(); // Set o properties string xml = o.ToString();

¿Cómo obtengo la representación XML de este objeto?


Aquí hay un código básico que ayudará a serializar los objetos C # en xml:

using System; public class clsPerson { public string FirstName; public string MI; public string LastName; } class class1 { static void Main(string[] args) { clsPerson p=new clsPerson(); p.FirstName = "Jeff"; p.MI = "A"; p.LastName = "Price"; System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(p.GetType()); x.Serialize(Console.Out, p); Console.WriteLine(); Console.ReadLine(); } }


Clase de extension:

using System.IO; using System.Xml; using System.Xml.Serialization; namespace MyProj.Extensions { public static class XmlExtension { public static string Serialize<T>(this T value) { if (value == null) return string.Empty; var xmlSerializer = new XmlSerializer(typeof(T)); using (var stringWriter = new StringWriter()) { using (var xmlWriter = XmlWriter.Create(stringWriter,new XmlWriterSettings{Indent = true})) { xmlSerializer.Serialize(xmlWriter, value); return stringWriter.ToString(); } } } } }

Uso:

Foo foo = new Foo{MyProperty="I have been serialized"}; string xml = foo.Serialize();

Simplemente haga referencia al espacio de nombres que contiene su método de extensión en el archivo en el que desea usarlo y funcionará (en mi ejemplo sería: using MyProj.Extensions; )

Tenga en cuenta que si desea que el método de extensión sea específico solo para una clase en particular (por ejemplo, Foo ), puede reemplazar el argumento T en el método de extensión, por ejemplo.

public static string Serialize(this Foo value){...}


Comenzaré con la copia de la respuesta de Ben Gripka:

public void Save(string FileName) { using (var writer = new System.IO.StreamWriter(FileName)) { var serializer = new XmlSerializer(this.GetType()); serializer.Serialize(writer, this); writer.Flush(); } }

Utilicé este código anteriormente. Pero la realidad demostró que esta solución es un poco problemática. Por lo general, la mayoría de los programadores simplemente serializan la configuración en guardar y deserializar la configuración en la carga. Este es un escenario optimista. Una vez que la serialización falló, por alguna razón, el archivo está parcialmente escrito, el archivo XML no está completo y no es válido. En consecuencia, la deserialización de XML no funciona y su aplicación puede fallar en el inicio. Si el archivo no es enorme, sugiero primero serializar el objeto a MemoryStream luego escribir la secuencia en el archivo. Este caso es especialmente importante si hay una serialización personalizada complicada. Nunca puedes probar todos los casos.

public void Save(string fileName) { //first serialize the object to memory stream, //in case of exception, the original file is not corrupted using (MemoryStream ms = new MemoryStream()) { var writer = new System.IO.StreamWriter(ms); var serializer = new XmlSerializer(this.GetType()); serializer.Serialize(writer, this); writer.Flush(); //if the serialization succeed, rewrite the file. File.WriteAllBytes(fileName, ms.ToArray()); } }

La deserialización en el escenario del mundo real debe contar con un archivo de serialización dañado, esto sucede en algún momento. La función de carga proporcionada por Ben Gripka está bien.

public static [ObjectType] Load(string fileName) { using (var stream = System.IO.File.OpenRead(fileName)) { var serializer = new XmlSerializer(typeof([ObjectType])); return serializer.Deserialize(stream) as [ObjectType]; } }

Y podría estar envuelto por algún escenario de recuperación. Es adecuado para archivos de configuración u otros archivos que se pueden eliminar en caso de problemas.

public static [ObjectType] LoadWithRecovery(string fileName) { try { return Load(fileName); } catch(Excetion) { File.Delete(fileName); //delete corrupted settings file return GetFactorySettings(); } }


Es un poco más complicado que llamar al método ToString de la clase, pero no mucho.

Aquí hay una función sencilla que puede usar para serializar cualquier tipo de objeto. Devuelve una cadena que contiene los contenidos XML serializados:

public string SerializeObject(object obj) { System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument(); System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType()); using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) { serializer.Serialize(ms, obj); ms.Position = 0; xmlDoc.Load(ms); return xmlDoc.InnerXml; } }


La siguiente función se puede copiar a cualquier objeto para agregar una función de guardar XML utilizando el espacio de nombres System.Xml.

/// <summary> /// Saves to an xml file /// </summary> /// <param name="FileName">File path of the new xml file</param> public void Save(string FileName) { using (var writer = new System.IO.StreamWriter(FileName)) { var serializer = new XmlSerializer(this.GetType()); serializer.Serialize(writer, this); writer.Flush(); } }

Para crear el objeto a partir del archivo guardado, agregue la siguiente función y reemplace [ObjectType] con el tipo de objeto que se creará.

/// <summary> /// Load an object from an xml file /// </summary> /// <param name="FileName">Xml file name</param> /// <returns>The object created from the xml file</returns> public static [ObjectType] Load(string FileName) { using (var stream = System.IO.File.OpenRead(FileName)) { var serializer = new XmlSerializer(typeof([ObjectType])); return serializer.Deserialize(stream) as [ObjectType]; } }


Modifiqué la mía para devolver una cadena en lugar de usar una variable de referencia como la de abajo

public static string Serialize<T>(this T value) { if (value == null) { return string.Empty; } try { var xmlserializer = new XmlSerializer(typeof(T)); var stringWriter = new StringWriter(); using (var writer = XmlWriter.Create(stringWriter)) { xmlserializer.Serialize(writer, value); return stringWriter.ToString(); } } catch (Exception ex) { throw new Exception("An error occurred", ex); } }

Su uso sería así:

var xmlString = obj.Serialize();


O puede agregar este método a su objeto:

public void Save(string filename) { var ser = new XmlSerializer(this.GetType()); using (var stream = new FileStream(filename, FileMode.Create)) ser.Serialize(stream, this); }


Para serializar un objeto, haga:

using (StreamWriter myWriter = new StreamWriter(path, false)) { XmlSerializer mySerializer = new XmlSerializer(typeof(your_object_type)); mySerializer.Serialize(myWriter, objectToSerialize); }

También recuerda que para que XmlSerializer funcione, necesitas un constructor sin parámetros.


Puede utilizar la función como a continuación para obtener XML serializado de cualquier objeto.

public static bool Serialize<T>(T value, ref string serializeXml) { if (value == null) { return false; } try { XmlSerializer xmlserializer = new XmlSerializer(typeof(T)); StringWriter stringWriter = new StringWriter(); XmlWriter writer = XmlWriter.Create(stringWriter); xmlserializer.Serialize(writer, value); serializeXml = stringWriter.ToString(); writer.Close(); return true; } catch (Exception ex) { return false; } }

Puedes llamar a esto desde el cliente.


Tienes que usar XmlSerializer para la serialización XML. A continuación se muestra un fragmento de muestra.

XmlSerializer xsSubmit = new XmlSerializer(typeof(MyObject)); var subReq = new MyObject(); var xml = ""; using(var sww = new StringWriter()) { using(XmlWriter writer = XmlWriter.Create(sww)) { xsSubmit.Serialize(writer, subReq); xml = sww.ToString(); // Your XML } }


mi código de trabajo Devuelve utf8 xml habilitar el espacio de nombres vacío.

// override StringWriter public class Utf8StringWriter : StringWriter { public override Encoding Encoding => Encoding.UTF8; } private string GenerateXmlResponse(Object obj) { Type t = obj.GetType(); var xml = ""; using (StringWriter sww = new Utf8StringWriter()) { using (XmlWriter writer = XmlWriter.Create(sww)) { var ns = new XmlSerializerNamespaces(); // add empty namespace ns.Add("", ""); XmlSerializer xsSubmit = new XmlSerializer(t); xsSubmit.Serialize(writer, obj, ns); xml = sww.ToString(); // Your XML } } return xml; }

Ejemplo devuelve respuesta Yandex api payment Aviso url:

<?xml version="1.0" encoding="utf-8"?><paymentAvisoResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" performedDatetime="2017-09-01T16:22:08.9747654+07:00" code="0" shopId="54321" invoiceId="12345" orderSumAmount="10643" />



string FilePath = ConfigurationReader.FileLocation; //Getting path value from web.config XmlSerializer serializer = new XmlSerializer(typeof(Devices)); //typeof(object) MemoryStream memStream = new MemoryStream(); serializer.Serialize(memStream, lstDevices);//lstdevices : I take result as a list. FileStream file = new FileStream(folderName + "//Data.xml", FileMode.Create, FileAccess.ReadWrite); //foldername:Specify the path to store the xml file memStream.WriteTo(file); file.Close();

Puede crear y almacenar el resultado como archivo xml en la ubicación deseada.