序列化一个对象到string

我有以下方法将一个对象保存到一个文件:

// 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(); } 

我承认我没有写(我只将它转换为一个扩展方法,采取了一个types参数)。

现在我需要它把xml作为一个string给我(而不是保存到一个文件)。 我正在研究它,但我还没有弄明白。

我认为这对于熟悉这些对象的人来说可能非常容易。 如果不是,我会最终弄清楚。

使用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(); } } 

请注意,在XmlSerializer构造函数中使用toSerialize.GetType()而不是typeof(T)非常重要:如果使用第一个代码覆盖T所有可能子类(这对方法有效),而使用后者在传递从T派生的types时将失败。 下面是一些激励这个语句的示例代码的链接,当使用typeof(T)时, XmlSerializer抛出一个Exception ,因为您将派生types的实例传递给一个调用在派生types的基类中定义的SerializeObject的方法: http : //ideone.com/1Z5J1 。

此外,Ideone使用Mono来执行代码; 实际使用Microsoft .NET运行时的Exception使用Ideone时显示的Message不同,但是会失败。

我知道这不是一个真正的问题的答案,但基于问题的投票数和接受的答案,我怀疑人们实际上是使用代码序列化一个对象的string。

使用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> 

更好的解决scheme是使用JSON序列化(最好的之一是Json.NET )。 要序列化一个对象:

 var userData = new UserData {UserId = 0}; var userDataString = JsonConvert.SerializeObject(userData); 

反序列化对象:

 var userData = JsonConvert.DeserializeObject<UserData>(userDataString); 

序列化的JSONstring如下所示:

 {"UserId":0} 

代码安全说明

关于接受的答案 ,在XmlSerializer构造函数中使用toSerialize.GetType()而不是typeof(T)非常重要:如果使用第一个代码覆盖所有可能的scheme,而使用后者则有时会失败。

下面是一些激励这个语句的示例代码的链接,当使用typeof(T)时, XmlSerializer抛出一个Exception,因为您将派生types的实例传递给调用SerializeObject<T>()的方法,派生types的基类: http : //ideone.com/1Z5J1 。 请注意,Ideone使用Mono来执行代码:使用Microsoft .NET运行时的实际exception具有与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(); } } 

序列化和反序列化:

  public static T Deserialize<T>(this string toDeserialize) { XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); StringReader textReader = new StringReader(toDeserialize); return (T)xmlSerializer.Deserialize(textReader); } public static string Serialize<T>(this T toSerialize) { XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); StringWriter textWriter = new StringWriter(); xmlSerializer.Serialize(textWriter, toSerialize); return textWriter.ToString(); } 

我的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()); } } } 
 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(); } } 

问题的内容提到XML,但由于问题是“序列化一个对象到string”我已经提供了代码序列化到JSON (使用Newtonsoft.Json库),因为这是更常见的情况下,这个答案。

 string jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(objToSerialize); 

我无法使用xhafan提供的JSONConvert方法

在.Net 4.5中,即使在添加“System.Web.Extensions”程序集引用后,我仍然无法访问JSONConvert。

但是,一旦添加了引用,就可以使用以下命令获取相同的string:

 JavaScriptSerializer js = new JavaScriptSerializer(); string jsonstring = js.Serialize(yourClassObject); 

在极less数情况下,您可能需要实现自己的string序列化。

但是,除非你知道你在做什么,否则这可能是一个主意。 (例如使用batch file序列化I / O)

像这样的东西会做的伎俩(这将很容易手动/批处理),但要小心,应该做一些更多的检查,如名称不包含换行符。

 public string name {get;set;} public int age {get;set;} Person(string serializedPerson) { string[] tmpArray = serializedPerson.Split('\n'); if(tmpArray.Length>2 && tmpArray[0].Equals("#")){ this.name=tmpArray[1]; this.age=int.TryParse(tmpArray[2]); }else{ throw new ArgumentException("Not a valid serialization of a person"); } } public string SerializeToString() { return "#\n" + name + "\n" + age; }