У меня есть класс C#, который я унаследовал. Я успешно "создал" объект. Но мне нужно сериализовать объект в 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-представление этого объекта?
Для сериализации XML необходимо использовать XmlSerializer. Ниже приведен пример фрагмента.
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
}
}
Я изменил мои, чтобы возвратить строку, а не использовать Реф переменной, как показано ниже.
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();
Следующие функции могут быть скопированы на любой объект, чтобы добавить 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();
}
}
Чтобы создать объект из сохраненного файла, добавьте следующую функцию и замените [тип объекта] с типом создаваемого объекта.
/// <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];
}
}
Расширение класса:
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();
Просто ссылки на пространство имен держа свой метод расширения в файл, который вы хотели бы использовать его и он'будете работать (в моем примере это будет: используя примет вид myproj.Расширения;
)
Обратите внимание, что если вы хотите сделать методом расширения, специфические для определенного класса(напр., Фу
), Вы можете заменить аргумент T
в метод расширения, например.
публичный статический строку сериализации(это ФОО значение){...}
Вы можете использовать функцию ниже, чтобы получить сериализованный 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;
}
}
Вы можете назвать это от клиента.
Я начну с копией ответа Бен 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());
}
}
Десериализации в реальном мире сценарий следует считать с поврежденного файла сериализации, это иногда случается. Функция нагрузку, оказываемую на Бен Gripka нормально.
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();
}
}
Чтобы сериализовать объект, выполните следующие действия:
using (StreamWriter myWriter = new StreamWriter(path, false))
{
XmlSerializer mySerializer = new XmlSerializer(typeof(your_object_type));
mySerializer.Serialize(myWriter, objectToSerialize);
}
Также помните, что для работы XmlSerializer необходим конструктор без параметров.
Голосуют все вышеперечисленные ответы верны. Это просто простейший вариант:
private string Serialize(Object o)
{
using (var writer = new StringWriter())
{
new XmlSerializer(o.GetType()).Serialize(writer, o);
return writer.ToString();
}
}
Это'ы немного сложнее, чем вызвать метод 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;
}
}
Вот хороший учебник о том, как это сделать
В основном для этого следует использовать класс System.Xml.Serialization.XmlSerializer
.
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-файла в нужное место.
мой рабочий код. Возвращает в 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 Яндекса платежных авизо адресу:
<?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" />
У меня есть простой способ, чтобы сериализовать объект в XML с помощью C#, он отлично работает и это'ы легко повторно использовать. Я знаю, что это старый нить, но я хотел, чтобы этот пост, потому что кто-то может найти это полезным.
Вот как я вызываю метод:
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);
}
}
Или вы можете добавить этот метод к вашему объекту:
public void Save(string filename)
{
var ser = new XmlSerializer(this.GetType());
using (var stream = new FileStream(filename, FileMode.Create))
ser.Serialize(stream, this);
}
Здесь'ы базовый код, который поможет сериализация объектов C# в 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();
}
}