例如
[DataContract]
public abstract class BaseClass
{
public abstract string id { get; set; }
}
[DataContract(Name = "class1")]
public class concreteClass1 : BaseClass
{
public concreteClass1() { }
[DataMember]
public override string id { get; set; }
[DataMember]
public string prop1 { get; set; }
[DataMember]
public string prop2 { get; set; }
}
[DataContract(Name = "class2")]
public class concreteClass2 : BaseClass
{
public concreteClass2() { }
[DataMember]
public override string id { get; set; }
[DataMember]
public string prop1 { get; set; }
[DataMember]
public string prop2 { get; set; }
}
当我尝试序列化包含其中一个具体类的字典时,如
static public void Main(string[] args){
Dictionary<string, BaseClass> items = new Dictionary<string, BaseClass>();
items.Add("1", new concreteClass1() { id = "1", prop1 = "blah1" });
items.Add("11", new concreteClass1() { id = "11", prop1 = "blah11" });
var serializer = new DataContractSerializer(items.GetType());
string xmlString = string.Empty;
using (var sw = new StringWriter())
{
using (var writer = new XmlTextWriter(sw))
{
writer.Formatting = System.Xml.Formatting.Indented;
serializer.WriteObject(writer, items );
writer.Flush();
xmlString = sw.ToString();
}
}
}
尝试WriteObject时出现此错误
键入&#39; ConsoleTest.Program + Base&#39;无法序列化。考虑标记 它与DataContractAttribute属性,并标记其所有 要使用DataMemberAttribute属性序列化的成员。 如果类型是集合,请考虑使用 CollectionDataContractAttribute。请参阅Microsoft .NET Framework 其他支持类型的文档。
有没有办法解决这个问题?
编辑:我也尝试在基类上使用KnownType但它没有工作
[DataContract]
[KnownType(typeof(concreteClass1))]
[KnownType(typeof(concreteClass2))]
public abstract class BaseClass
{
public abstract string id { get; set; }
}
答案 0 :(得分:1)
试试这个......
使用....
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Xml;
班级......
[DataContract]
[KnownType(typeof(concreteClass1))]
[KnownType(typeof(concreteClass2))]
public abstract class BaseClass
{
[DataMember]
public abstract string id { get; set; }
}
[DataContract(Name = "class1")]
public class concreteClass1 : BaseClass
{
public concreteClass1() { }
[DataMember]
public override string id { get; set; }
[DataMember]
public string prop1 { get; set; }
[DataMember]
public string prop2 { get; set; }
}
[DataContract(Name = "class2")]
public class concreteClass2 : BaseClass
{
public concreteClass2() { }
[DataMember]
public override string id { get; set; }
[DataMember]
public string prop1 { get; set; }
[DataMember]
public string prop2 { get; set; }
}
代码。
static void Main(string[] args)
{
Dictionary<string, BaseClass> items = new Dictionary<string, BaseClass>();
items.Add("1", new concreteClass1() { id = "1", prop1 = "blah1" });
items.Add("11", new concreteClass1() { id = "11", prop1 = "blah11" });
// this should work too....
items.Add("999", new concreteClass2() { id = "999", prop1 = "blah999" });
items.Add("888", new concreteClass2() { id = "888", prop1 = "blah888" });
//Serialize(items);
var serializer = new DataContractSerializer(items.GetType());
string xmlString = string.Empty;
try
{
using (var sw = new StringWriter())
{
using (var writer = new XmlTextWriter(sw))
{
writer.Formatting = System.Xml.Formatting.Indented;
serializer.WriteObject(writer, items);
writer.Flush();
xmlString = sw.ToString();
}
}
}
catch (Exception)
{
throw;
}
}
///////////////////// UPDATE /////////////////////
作为一点奖励(我觉得我没有看到我的25分)这里有两个函数可以序列化和反序列化一个通用对象......
public static void Serialize<T>(T data)
{
try // try to serialize the collection to a file
{
using (Stream stream = File.Open("data.xml", FileMode.Create))
{
// create DataContractSerializer
DataContractSerializer serializer = new DataContractSerializer(typeof (T));
// serialize the collection (EmployeeList1) to file (stream)
serializer.WriteObject(stream, data);
}
}
catch (IOException)
{
}
}
public static T Deserialize<T>() where T : new()
{
// Create an instance of T
T ReturnListOfT = CreateInstance<T>();
// Try to Deserialize from file stream
try
{
using (Stream stream = File.Open("data.xml", FileMode.Open))
{
// create DataContractSerializer
DataContractSerializer serializer = new DataContractSerializer(typeof (T));
// deserialize the collection (Employee) from file (stream)
ReturnListOfT = (T)serializer.ReadObject(stream);
}
}
catch (IOException)
{
}
return (T)ReturnListOfT;
}
// function to create instance of T
public static T CreateInstance<T>() where T : new()
{
return (T)Activator.CreateInstance(typeof(T));
}
而不是必须手动修改XML,您可以使用现有类反序列化对象(来自文件,在示例'data.xml'中)并创建用户界面以允许用户修改属性object \ classes,然后将修改后的对象重新保存\序列化回文件.....