我有以下抽象类结构:
public abstract class Template
{
// Some properties and methods defined
}
public abstract class Template<TTemplate> : Template where TTemplate : Template
{
// No new properties defined, but methods overriden
}
然后,我使用这些模板类作为模型的一部分:
public abstract class Model
{
public Template Template {get;set;}
public Model(Template t) {Template = t;}
// More properties and methods
}
public abstract class Model<TModel, TTemplate> : Model where TModel : Model where TTemplate : Template
{
public new TTemplate template {get {return (TTemplate)base.Template;} set {base.Template = value;}}
public Model(TTemplate t) : base(t) {}
// Override some methods but no new properties
}
然后,我创建模板和模型的具体类,并在我的项目中使用它们。这些具体类定义了抽象基类中指定的附加属性。当需要序列化模型类时,我的问题就出现了。我使用反射来查找模型或模板的所有继承类型,并将它们传递到 XmlSerializer 中,以便它可以正确序列化我的抽象类。但是,我遇到了一个例外
There was an error reflecting type **ConcreteModel**.
System.InvalidOperationException:反映属性时发生错误
'模板'。 ---> System.InvalidOperationException:成员
ConcreteTemplate 类型的 ModelOfConcreteModelConcreteTemplate.Template 隐藏
Template 类型的基类成员 Model.Template。使用 XmlElementAttribute 或 XmlAttributeAttribute 指定新名称。
我碰到这篇文章在谷歌群组上 https://groups.google.com/forum/#!topic/microsoft.public.dotnet.xml/QxItJT-SwiI从 2003 年开始,它旨在给出答案,但我不确定如何实施该修复(或者它是否在 13 年后仍然有效)。它确实表明该错误消息具有误导性,因为该消息提出的解决方案不起作用。
如果我从 Model.Template 和类型化 Model 类中删除“set”访问器(例如,仅通过构造函数设置它),则该类可以很好地序列化 - 尽管没有 Template 属性。有没有一种方法可以对隐藏来自(n)(抽象)基类的属性的类进行 XML 序列化,而无需在每个继承的类上实现 IXmlSerialized?
我碰到这个帖子 http://forums.asp.net/t/1277541.aspx?XML%20Serializaton%20of%20LINQ%20to%20SQL%20object%20that%20inherits%20from%20external%20resource作者:david.woodward,展示了处理这种情况的可行且可行的方法(即,当更改基类不是一个选项时)。它建议提供XmlAttributeOverrides
to the XmlSerializer
.
使用您提供的对象模型,以下代码说明了其用法。它的工作原理是明确告诉XmlSerializer
在本例中忽略基类中的隐藏属性Model.Template
.
using System;
using System.IO;
using System.Text;
using System.Xml.Serialization;
class Program
{
static void Main(string[] args)
{
ConcreteTemplate ct = new ConcreteTemplate() { SomeProperty = "hello" };
ConcreteGenericModel cgm = new ConcreteGenericModel(ct);
XmlAttributeOverrides attrOverides = new XmlAttributeOverrides();
XmlAttributes attrs = new XmlAttributes() { XmlIgnore = true };
attrOverides.Add(typeof(Model), "Template", attrs);
Type[] extraTypes = new Type[0];
XmlSerializer serializer = new XmlSerializer(typeof(ConcreteGenericModel), attrOverides, extraTypes, null, null);
StringBuilder sb = new StringBuilder();
using (StringWriter writer = new StringWriter(sb))
serializer.Serialize(writer, cgm);
string serializedClass = sb.ToString();
Console.WriteLine(serializedClass);
ConcreteGenericModel deserializedCgm;
using (StringReader reader = new StringReader(serializedClass))
deserializedCgm = (ConcreteGenericModel)serializer.Deserialize(reader);
Console.ReadLine();
}
}
public abstract class Template
{
// Some properties and methods defined
public virtual string SomeProperty { get; set; }
}
public abstract class Template<TTemplate> : Template where TTemplate : Template
{
// No new properties defined, but methods overriden
}
public class ConcreteTemplate : Template { }
public abstract class Model
{
public Model() { }
public Template Template { get; set; }
public Model(Template t) { Template = t; }
// More properties and methods
}
public class ConcreteModel : Model
{
public ConcreteModel(Template t) : base(t) { }
}
public abstract class Model<TModel, TTemplate> : Model
where TModel : Model
where TTemplate : Template
{
public Model() { }
public new TTemplate Template { get { return (TTemplate)base.Template; } set { base.Template = value; } }
public Model(TTemplate t) : base(t) { }
// Override some methods but no new properties
}
public class ConcreteGenericModel : Model<ConcreteModel, ConcreteTemplate>
{
public ConcreteGenericModel() { }
public ConcreteGenericModel(ConcreteTemplate t) : base(t) { }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)