Сериализация объекта в XML
У меня есть класс С#, который я унаследовал. Я успешно "построил" объект. Но мне нужно сериализовать объект в XML. Есть ли простой способ сделать это?
Похоже, что класс был настроен для сериализации, но я не уверен, как получить представление XML. Определение моего класса выглядит следующим образом:
[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
{
...
}
Вот что я думал, что могу сделать, но он не работает:
MyObject o = new MyObject();
// Set o properties
string xml = o.ToString();
Как получить XML-представление этого объекта?
Ответы
Ответ 1
Вы должны использовать XmlSerializer для сериализации XML. Ниже приведен пример фрагмента.
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
}
}
Ответ 2
Я модифицировал мой, чтобы вернуть строку, а не использовать переменную ref, как показано ниже.
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);
}
}
Его использование будет таким:
var xmlString = obj.Serialize();
Ответ 3
Следующая функция может быть скопирована на любой объект, чтобы добавить функцию сохранения XML, используя пространство имен 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();
}
}
Чтобы создать объект из сохраненного файла, добавьте следующую функцию и замените [ObjectType] на тип объекта, который будет создан.
/// <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];
}
}
Ответ 4
Вы можете использовать функцию, как показано ниже, для получения сериализованного XML из любого объекта.
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;
}
}
Вы можете вызвать это от клиента.
Ответ 5
Класс расширения:
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();
}
}
}
}
}
Использование:
Foo foo = new Foo{MyProperty="I have been serialized"};
string xml = foo.Serialize();
Просто укажите пространство имен, в котором содержится ваш метод расширения, в файле, который вы хотели бы использовать, и он будет работать (в моем примере это будет: using MyProj.Extensions;
)
Обратите внимание, что если вы хотите сделать метод расширения конкретным только для определенного класса (например, Foo
), вы можете заменить аргумент T
в методе расширения, например.
public static string Serialize(this Foo value){...}
Ответ 6
Для сериализации объекта выполните:
using (StreamWriter myWriter = new StreamWriter(path, false))
{
XmlSerializer mySerializer = new XmlSerializer(typeof(your_object_type));
mySerializer.Serialize(myWriter, objectToSerialize);
}
Также помните, что для работы XmlSerializer вам нужен конструктор без параметров.
Ответ 7
Я начну с ответа на копию 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();
}
}
Я использовал этот код раньше. Но реальность показала, что это решение немного проблематично. Обычно большинство программистов просто сериализуют настройки при сохранении и десериализации настроек при загрузке. Это оптимистический сценарий. Как только сериализация завершилась неудачно, по какой-то причине файл частично написан, файл XML не является полным и недействителен. В результате десериализация XML не работает, и ваше приложение может сработать при запуске. Если файл не огромен, я предлагаю сначала сериализовать объект MemoryStream
, а затем записать поток в файл. Этот случай особенно важен, если есть некоторая сложная пользовательская сериализация. Вы никогда не сможете проверить все случаи.
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());
}
}
Дезериализация в сценарии реального мира должна учитываться с поврежденным файлом сериализации, это происходит когда-то. Функция загрузки, предоставляемая Бен Грипкой, прекрасна.
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];
}
}
И это может быть обернуто некоторым сценарием восстановления. Он подходит для файлов настроек или других файлов, которые могут быть удалены в случае возникновения проблем.
public static [ObjectType] LoadWithRecovery(string fileName)
{
try
{
return Load(fileName);
}
catch(Excetion)
{
File.Delete(fileName); //delete corrupted settings file
return GetFactorySettings();
}
}
Ответ 8
Это немного сложнее, чем вызов метода ToString
для класса, но не много.
Здесь представлена простая функция выгрузки, которую вы можете использовать для сериализации любого типа объекта. Он возвращает строку, содержащую сериализованное содержимое XML:
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;
}
}
Ответ 9
Вот хороший учебник о том, как это сделать
Для этого вы должны использовать класс System.Xml.Serialization.XmlSerializer
.
Ответ 10
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();
Вы можете создать и сохранить результат в виде XML файла в нужном месте.
Ответ 11
мой рабочий код. Возвращает utf8 xml, разрешает пустое пространство имен.
// 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;
}
Пример возвращает ответ Яндекс-api-платеж 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" />
Ответ 12
Или вы можете добавить этот метод к своему объекту:
public void Save(string filename)
{
var ser = new XmlSerializer(this.GetType());
using (var stream = new FileStream(filename, FileMode.Create))
ser.Serialize(stream, this);
}
Ответ 13
Все приведенные выше ответы верны. Это просто самая простая версия:
private string Serialize(Object o)
{
using (var writer = new StringWriter())
{
new XmlSerializer(o.GetType()).Serialize(writer, o);
return writer.ToString();
}
}
Ответ 14
У меня есть простой способ сериализации объекта в XML с использованием С#, он прекрасно работает и его можно многократно использовать. Я знаю, что это старая ветка, но я хотел опубликовать это, потому что кто-то может найти это полезным для них.
Вот как я называю метод:
var objectToSerialize = new MyObject();
var xmlString = objectToSerialize.ToXmlString();
Вот класс, который делает работу:
Примечание. Поскольку это методы расширения, они должны находиться в статическом классе.
using System.IO;
using System.Xml.Serialization;
public static class XmlTools
{
public static string ToXmlString<T>(this T input)
{
using (var writer = new StringWriter())
{
input.ToXml(writer);
return writer.ToString();
}
}
private static void ToXml<T>(this T objectToSerialize, StringWriter writer)
{
new XmlSerializer(typeof(T)).Serialize(writer, objectToSerialize);
}
}
Ответ 15
Вот основной код, который поможет сериализовать объекты С# в 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();
}
}