我有以下方法来保存一个对象到一个文件:
// 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();
}
我承认这不是我写的(我只是把它转换成一个接受类型参数的扩展方法)。
现在我需要它把xml作为字符串返回给我(而不是保存到文件中)。我正在调查这件事,但我还没有弄清楚。
我想对于熟悉这些物体的人来说,这可能很简单。如果没有,我最终会弄清楚的。
我知道这不是问题的真正答案,但根据问题的投票数和接受的答案,我怀疑人们实际上是在使用代码将对象序列化为字符串。
使用XML序列化会给输出增加不必要的额外文本垃圾。
对于下面的类
public class UserData
{
public int UserId { get; set; }
}
它生成
<?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>
更好的解决方案是使用JSON序列化(最好的方法之一是Json.NET)。
序列化一个对象:
var userData = new UserData {UserId = 0};
var userDataString = JsonConvert.SerializeObject(userData);
反序列化一个对象:
var userData = JsonConvert.DeserializeObject<UserData>(userDataString);
序列化的JSON字符串看起来像这样:
{"UserId":0}
[VB]
Public Function XmlSerializeObject(ByVal obj As Object) As String
Dim xmlStr As String = String.Empty
Dim settings As New XmlWriterSettings()
settings.Indent = False
settings.OmitXmlDeclaration = True
settings.NewLineChars = String.Empty
settings.NewLineHandling = NewLineHandling.None
Using stringWriter As New StringWriter()
Using xmlWriter__1 As XmlWriter = XmlWriter.Create(stringWriter, settings)
Dim serializer As New XmlSerializer(obj.[GetType]())
serializer.Serialize(xmlWriter__1, obj)
xmlStr = stringWriter.ToString()
xmlWriter__1.Close()
End Using
stringWriter.Close()
End Using
Return xmlStr.ToString
End Function
Public Function XmlDeserializeObject(ByVal data As [String], ByVal objType As Type) As Object
Dim xmlSer As New System.Xml.Serialization.XmlSerializer(objType)
Dim reader As TextReader = New StringReader(data)
Dim obj As New Object
obj = DirectCast(xmlSer.Deserialize(reader), Object)
Return obj
End Function
[C#]
public string XmlSerializeObject(object obj)
{
string xmlStr = String.Empty;
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = false;
settings.OmitXmlDeclaration = true;
settings.NewLineChars = String.Empty;
settings.NewLineHandling = NewLineHandling.None;
using (StringWriter stringWriter = new StringWriter())
{
using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter, settings))
{
XmlSerializer serializer = new XmlSerializer( obj.GetType());
serializer.Serialize(xmlWriter, obj);
xmlStr = stringWriter.ToString();
xmlWriter.Close();
}
}
return xmlStr.ToString();
}
public object XmlDeserializeObject(string data, Type objType)
{
XmlSerializer xmlSer = new XmlSerializer(objType);
StringReader reader = new StringReader(data);
object obj = new object();
obj = (object)(xmlSer.Deserialize(reader));
return obj;
}
使用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();
}
}
Note, it is important to use toSerialize.GetType() instead of typeof(T) in XmlSerializer constructor: if you use the first one the code covers all possible subclasses of T (which are valid for the method), while using the latter one will fail when passing a type derived from T.
Here is a link with some example code that motivate this statement, with XmlSerializer throwing an Exception when typeof(T) is used, because you pass an instance of a derived type to a method that calls SerializeObject that is defined in the derived type's base class: http://ideone.com/1Z5J1.
此外,Ideone使用Mono来执行代码;使用Microsoft . net运行时得到的实际异常与Ideone上显示的异常有不同的消息,但它同样失败。