c# – 使用不同类的通用列表XML序列化
我有以下代码:
BaseContent.cs public class BaseContent { // Some auto properties } News.cs public class News : BaseContent { // Some more auto properties } Events.cs public class Event : BaseContent { // Some more auto properites } GenericResponse.cs public class GenericResponse<T> { [XmlArray("Content")] [XmlArrayItem("NewsObject",typeof(News)] [XmlArrayItem("EventObject",typeof(Event)] public List<T> ContentItems { get; set; } } NewsResponse.cs public class NewsResponse : GenericResponse<News> {} EventResponse.cs public class EventResponse : GenericResponse<Event> {} 你可以看到,我有一个基类BaseContent和从它派生的两个类.接下来我有一个通用响应类,因为xml文件的结构总是相同的,但是在某些属性中它们有所不同. 我以为我可以用[XmlArrayItem]指定用于特定类的名称.但是现在我得到错误:
我无法添加此引用,因为我正在使用Windows 8应用程序. 如果我注释掉其中一个[XmlArrayItem],它的工作效果很好. 任何人都有一个想法来解决这个问题? 更新 解决方法
编辑:随意下载
demo project
您没有提供对象的所有属性,所以允许我添加一些 – 就像一个例子: public class BaseContent { [XmlAttribute("Name")] public string Name { get; set; } } [XmlType(TypeName = "EventObject")] public class Event : BaseContent { [XmlAttribute("EventId")] public int EventId { get; set; } } [XmlType(TypeName = "NewsObject")] public class News : BaseContent { [XmlAttribute("NewsId")] public int NewsId { get; set; } } GenericResponse.cs可以这样定义 – 不需要为数组项指定typeof: public class GenericResponse<T> { [XmlArray("Content")] public List<T> ContentItems { get; set; } public GenericResponse() { this.ContentItems = new List<T>(); } } 然后你有响应类: public class EventResponse : GenericResponse<Event> { } public class NewsResponse : GenericResponse<News> { } 示例1:序列化EventResponse对象 var response = new EventResponse { ContentItems = new List<Event> { new Event { EventId = 1,Name = "Event 1" },new Event { EventId = 2,Name = "Event 2" } } }; string xml = XmlSerializer<EventResponse>.Serialize(response); 输出XML: <?xml version="1.0" encoding="utf-8"?> <EventResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Content> <EventObject Name="Event 1" EventId="1" /> <EventObject Name="Event 2" EventId="2" /> </Content> </EventResponse> 如果您尝试与NewsResponse相同,它将正常工作. BTW我使用我的generic XmlSerializer,点击链接了解更多. XmlSerializer.cs: /// <summary> /// XML serializer helper class. Serializes and deserializes objects from/to XML /// </summary> /// <typeparam name="T">The type of the object to serialize/deserialize. /// Must have a parameterless constructor and implement <see cref="Serializable"/></typeparam> public class XmlSerializer<T> where T: class,new() { /// <summary> /// Deserializes a XML string into an object /// Default encoding: <c>UTF8</c> /// </summary> /// <param name="xml">The XML string to deserialize</param> /// <returns>An object of type <c>T</c></returns> public static T Deserialize(string xml) { return Deserialize(xml,Encoding.UTF8,null); } /// <summary> /// Deserializes a XML string into an object /// Default encoding: <c>UTF8</c> /// </summary> /// <param name="xml">The XML string to deserialize</param> /// <param name="encoding">The encoding</param> /// <returns>An object of type <c>T</c></returns> public static T Deserialize(string xml,Encoding encoding) { return Deserialize(xml,encoding,null); } /// <summary> /// Deserializes a XML string into an object /// </summary> /// <param name="xml">The XML string to deserialize</param> /// <param name="settings">XML serialization settings. <see cref="System.Xml.XmlReaderSettings"/></param> /// <returns>An object of type <c>T</c></returns> public static T Deserialize(string xml,XmlReaderSettings settings) { return Deserialize(xml,settings); } /// <summary> /// Deserializes a XML string into an object /// </summary> /// <param name="xml">The XML string to deserialize</param> /// <param name="encoding">The encoding</param> /// <param name="settings">XML serialization settings. <see cref="System.Xml.XmlReaderSettings"/></param> /// <returns>An object of type <c>T</c></returns> public static T Deserialize(string xml,Encoding encoding,XmlReaderSettings settings) { if (string.IsNullOrEmpty(xml)) throw new ArgumentException("XML cannot be null or empty","xml"); XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); using (MemoryStream memoryStream = new MemoryStream(encoding.GetBytes(xml))) { using (XmlReader xmlReader = XmlReader.Create(memoryStream,settings)) { return (T) xmlSerializer.Deserialize(xmlReader); } } } /// <summary> /// Deserializes a XML file. /// </summary> /// <param name="filename">The filename of the XML file to deserialize</param> /// <returns>An object of type <c>T</c></returns> public static T DeserializeFromFile(string filename) { return DeserializeFromFile(filename,new XmlReaderSettings()); } /// <summary> /// Deserializes a XML file. /// </summary> /// <param name="filename">The filename of the XML file to deserialize</param> /// <param name="settings">XML serialization settings. <see cref="System.Xml.XmlReaderSettings"/></param> /// <returns>An object of type <c>T</c></returns> public static T DeserializeFromFile(string filename,XmlReaderSettings settings) { if (string.IsNullOrEmpty(filename)) throw new ArgumentException("filename","XML filename cannot be null or empty"); if (! File.Exists(filename)) throw new FileNotFoundException("Cannot find XML file to deserialize",filename); // Create the stream writer with the specified encoding using (XmlReader reader = XmlReader.Create(filename,settings)) { System.Xml.Serialization.XmlSerializer xmlSerializer = new System.Xml.Serialization.XmlSerializer(typeof(T)); return (T) xmlSerializer.Deserialize(reader); } } /// <summary> /// Serialize an object /// </summary> /// <param name="source">The object to serialize</param> /// <returns>A XML string that represents the object to be serialized</returns> public static string Serialize(T source) { // indented XML by default return Serialize(source,null,GetIndentedSettings()); } /// <summary> /// Serialize an object /// </summary> /// <param name="source">The object to serialize</param> /// <param name="namespaces">Namespaces to include in serialization</param> /// <returns>A XML string that represents the object to be serialized</returns> public static string Serialize(T source,XmlSerializerNamespaces namespaces) { // indented XML by default return Serialize(source,namespaces,GetIndentedSettings()); } /// <summary> /// Serialize an object /// </summary> /// <param name="source">The object to serialize</param> /// <param name="settings">XML serialization settings. <see cref="System.Xml.XmlWriterSettings"/></param> /// <returns>A XML string that represents the object to be serialized</returns> public static string Serialize(T source,XmlWriterSettings settings) { return Serialize(source,settings); } /// <summary> /// Serialize an object /// </summary> /// <param name="source">The object to serialize</param> /// <param name="namespaces">Namespaces to include in serialization</param> /// <param name="settings">XML serialization settings. <see cref="System.Xml.XmlWriterSettings"/></param> /// <returns>A XML string that represents the object to be serialized</returns> public static string Serialize(T source,XmlSerializerNamespaces namespaces,XmlWriterSettings settings) { if (source == null) throw new ArgumentNullException("source","Object to serialize cannot be null"); string xml = null; XmlSerializer serializer = new XmlSerializer(source.GetType()); using (MemoryStream memoryStream = new MemoryStream()) { using (XmlWriter xmlWriter = XmlWriter.Create(memoryStream,settings)) { System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(T)); x.Serialize(xmlWriter,source,namespaces); memoryStream.Position = 0; // rewind the stream before reading back. using (StreamReader sr = new StreamReader(memoryStream)) { xml = sr.ReadToEnd(); } } } return xml; } /// <summary> /// Serialize an object to a XML file /// </summary> /// <param name="source">The object to serialize</param> /// <param name="filename">The file to generate</param> public static void SerializeToFile(T source,string filename) { // indented XML by default SerializeToFile(source,filename,GetIndentedSettings()); } /// <summary> /// Serialize an object to a XML file /// </summary> /// <param name="source">The object to serialize</param> /// <param name="filename">The file to generate</param> /// <param name="namespaces">Namespaces to include in serialization</param> public static void SerializeToFile(T source,string filename,XmlSerializerNamespaces namespaces) { // indented XML by default SerializeToFile(source,GetIndentedSettings()); } /// <summary> /// Serialize an object to a XML file /// </summary> /// <param name="source">The object to serialize</param> /// <param name="filename">The file to generate</param> /// <param name="settings">XML serialization settings. <see cref="System.Xml.XmlWriterSettings"/></param> public static void SerializeToFile(T source,XmlWriterSettings settings) { SerializeToFile(source,settings); } /// <summary> /// Serialize an object to a XML file /// </summary> /// <param name="source">The object to serialize</param> /// <param name="filename">The file to generate</param> /// <param name="namespaces">Namespaces to include in serialization</param> /// <param name="settings">XML serialization settings. <see cref="System.Xml.XmlWriterSettings"/></param> public static void SerializeToFile(T source,"Object to serialize cannot be null"); XmlSerializer serializer = new XmlSerializer(source.GetType()); using (XmlWriter xmlWriter = XmlWriter.Create(filename,settings)) { System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(T)); x.Serialize(xmlWriter,namespaces); } } #region Private methods private static XmlWriterSettings GetIndentedSettings() { XmlWriterSettings xmlWriterSettings = new XmlWriterSettings(); xmlWriterSettings.Indent = true; xmlWriterSettings.IndentChars = "t"; return xmlWriterSettings; } #endregion } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |