序列化一个对象到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; }