use*_*166 264 c# xml-serialization
我有一个我继承的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
{
...
}
Run Code Online (Sandbox Code Playgroud)
这是我认为我可以做的,但它不起作用:
MyObject o = new MyObject();
// Set o properties
string xml = o.ToString();
Run Code Online (Sandbox Code Playgroud)
如何获取此对象的XML表示?
Ram*_*Vel 469
您必须使用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
}
}
Run Code Online (Sandbox Code Playgroud)
Kwe*_*wex 112
我修改了我的返回字符串,而不是像下面那样使用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);
}
}
Run Code Online (Sandbox Code Playgroud)
它的用法如下:
var xmlString = obj.Serialize();
Run Code Online (Sandbox Code Playgroud)
Ben*_*pka 40
可以使用System.Xml命名空间将以下函数复制到任何对象以添加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();
}
}
Run Code Online (Sandbox Code Playgroud)
要从保存的文件创建对象,请添加以下函数,并将[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];
}
}
Run Code Online (Sandbox Code Playgroud)
Ale*_*ert 31
扩展类:
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();
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
Foo foo = new Foo{MyProperty="I have been serialized"};
string xml = foo.Serialize();
Run Code Online (Sandbox Code Playgroud)
只是引用该命名空间牵着你的扩展方法在文件中,你想在使用它,它会工作(在我的例子那就是:using MyProj.Extensions;)
请注意,如果要使扩展方法仅针对特定类(例如,Foo),则可以替换T扩展方法中的参数,例如.
public static string Serialize(this Foo value){...}
Imr*_*rul 29
您可以使用下面的函数从任何对象获取序列化的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;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以从客户端调用此方法.
Rox*_*Rox 18
要序列化对象,请执行以下操作:
using (StreamWriter myWriter = new StreamWriter(path, false))
{
XmlSerializer mySerializer = new XmlSerializer(typeof(your_object_type));
mySerializer.Serialize(myWriter, objectToSerialize);
}
Run Code Online (Sandbox Code Playgroud)
还要记住,要使XmlSerializer工作,您需要一个无参数构造函数.
Tom*_*bes 18
我将从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();
}
}
Run Code Online (Sandbox Code Playgroud)
我之前使用过这段代码.但现实表明,这个解决方案有点问题.通常,大多数程序员只是在加载时序列化设置保存和反序列化设置.这是一个乐观的情景.一旦序列化失败,由于某种原因,文件被部分写入,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());
}
}
Run Code Online (Sandbox Code Playgroud)
现实世界场景中的反序列化应该与损坏的序列化文件一起计算,它会在某个时间发生.Ben 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];
}
}
Run Code Online (Sandbox Code Playgroud)
它可以被一些恢复方案包裹起来.它适用于设置文件或其他可在出现问题时删除的文件.
public static [ObjectType] LoadWithRecovery(string fileName)
{
try
{
return Load(fileName);
}
catch(Excetion)
{
File.Delete(fileName); //delete corrupted settings file
return GetFactorySettings();
}
}
Run Code Online (Sandbox Code Playgroud)
以上所有建议的答案都是正确的。这是最简单的版本:
private string Serialize(Object o)
{
using (var writer = new StringWriter())
{
new XmlSerializer(o.GetType()).Serialize(writer, o);
return writer.ToString();
}
}
Run Code Online (Sandbox Code Playgroud)
它比调用ToString类的方法要复杂一点,但并不多.
这是一个简单的drop-in函数,可用于序列化任何类型的对象.它返回一个包含序列化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;
}
}
Run Code Online (Sandbox Code Playgroud)
我有一种使用 C# 将对象序列化为 XML 的简单方法,它工作得很好并且高度可重用。我知道这是一个较旧的线程,但我想发布它,因为有人可能会发现这对他们有帮助。
这是我调用该方法的方式:
var objectToSerialize = new MyObject();
var xmlString = objectToSerialize.ToXmlString();
Run Code Online (Sandbox Code Playgroud)
这是完成工作的类:
注意:由于这些是扩展方法,因此它们需要位于静态类中。
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);
}
}
Run Code Online (Sandbox Code Playgroud)
基于上述解决方案,这里有一个扩展类,您可以使用它来序列化和反序列化任何对象。任何其他 XML 属性都由您决定。
只需像这样使用它:
string s = new MyObject().Serialize(); // to serialize into a string
MyObject b = s.Deserialize<MyObject>();// deserialize from a string
internal static class Extensions
{
public static T Deserialize<T>(this string value)
{
var xmlSerializer = new XmlSerializer(typeof(T));
return (T)xmlSerializer.Deserialize(new StringReader(value));
}
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();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的工作代码。返回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;
}
Run Code Online (Sandbox Code Playgroud)
示例返回响应 Yandex 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" />
Run Code Online (Sandbox Code Playgroud)