Vac*_*ano 294 c# string serialization xml-serialization
我有以下方法将对象保存到文件:
// 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();
}
Run Code Online (Sandbox Code Playgroud)
我承认我没有写它(我只将其转换为带有类型参数的扩展方法).
现在我需要它将xml作为字符串返回给我(而不是将其保存到文件中).我正在研究它,但我还没想到它.
我认为对于熟悉这些对象的人来说这可能很容易.如果不是,我最终会弄明白.
dtb*_*dtb 500
使用StringWriter
而不是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();
}
}
Run Code Online (Sandbox Code Playgroud)
注意,使用toSerialize.GetType()
而不是typeof(T)
在XmlSerializer构造函数中使用是很重要的:如果使用第一个代码,代码将涵盖所有可能的子类T
(对方法有效),而使用后者则在传递派生类型时会失败T
.下面是一些示例代码的链接,它激发了这个语句,XmlSerializer
抛出了一个Exception
when typeof(T)
,因为你将一个派生类型的实例传递给一个方法,该方法调用派生类型的基类中定义的SerializeObject:http:// ideone .com/1Z5J1.
此外,Ideone使用Mono执行代码; Exception
使用Microsoft .NET运行时的实际Message
情况与Ideone上显示的实际情况有所不同,但它的失败方式却相同.
xha*_*fan 69
我知道这不是问题的答案,但根据问题的投票数和接受的答案,我怀疑人们实际上是在使用代码将对象序列化为字符串.
使用XML序列化会在输出中添加不必要的额外文本垃圾.
对于以下课程
public class UserData
{
public int UserId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
它会产生
<?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>
Run Code Online (Sandbox Code Playgroud)
更好的解决方案是使用JSON序列化(其中最好的是Json.NET).要序列化对象:
var userData = new UserData {UserId = 0};
var userDataString = JsonConvert.SerializeObject(userData);
Run Code Online (Sandbox Code Playgroud)
要反序列化对象:
var userData = JsonConvert.DeserializeObject<UserData>(userDataString);
Run Code Online (Sandbox Code Playgroud)
序列化的JSON字符串如下所示:
{"UserId":0}
Run Code Online (Sandbox Code Playgroud)
ADM*_*-IT 57
序列化和反序列化:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
Ful*_*vio 37
关于接受的答案,重要的是使用toSerialize.GetType()
而不是typeof(T)
在XmlSerializer
构造函数中使用:如果使用第一个代码,则代码涵盖所有可能的方案,而使用后者则有时会失败.
这是一个链接,其中包含一些激励此语句的示例代码,XmlSerializer
在typeof(T)
使用时抛出一个Exception ,因为您将派生类型的实例传递给调用SerializeObject<T>()
派生类型的基类中定义的方法:http:// ideone .com/1Z5J1.请注意,Ideone使用Mono来执行代码:使用Microsoft .NET运行时获得的实际异常消息与Ideone上显示的消息不同,但它失败的方式相同.
为了完整起见,我在这里发布完整的代码示例以供将来参考,以防Ideone(我发布代码的地方)将来变得不可用:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
oPl*_*ess 10
我的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());
}
}
}
Run Code Online (Sandbox Code Playgroud)
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();
}
}
Run Code Online (Sandbox Code Playgroud)