我在将c#类序列化为具有基类的XML文件时出现问题...这是一个简单的例子:
namespace Domain
{
[Serializable]
public class ClassA
{
public virtual int MyProperty
{
get; set;
}
}
}
namespace Derived
{
public class ClassA : Domain.ClassA
{
public override int MyProperty
{
get { return 1; } set { /* Do Nothing */ }
}
}
}
当我尝试序列化Derived.ClassA的一个实例时,我收到以下异常:
InvalidOperationException(Types'Domain.ClassA'和'Derived.ClassA'都使用来自命名空间的XML类型名称'ClassA'。使用XML属性为该类型指定唯一的XML名称和/或命名空间。)
问题是我想创建一个简单定义XML文件结构的基类,然后允许其他任何人从该类派生来插入业务规则,但格式化将来自基础
这是可能的,如果是这样,我如何将基类归因于允许这个?
答案 0 :(得分:5)
这对我们起了作用。
[XmlType(TypeName = "DerivedClassA")]
答案 1 :(得分:2)
如果您可以将派生类重命名为与其基类不同的内容,则可以使用XmlAttributeOverrides
执行此操作:
// For ClassB, which derives from ClassA
XmlAttributes attributes = new XmlAttributes();
attributes.XmlRoot = new XmlRootAttribute("ClassA");
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
overrides.Add(typeof(ClassB), attributes);
XmlSerializer serializer = new XmlSerializer(typeof(ClassB), overrides);
这将序列化为<ClassA> ... </ClassA>
,并可以将其序列化为ClassB
个实例。
据我所知,当基类和派生类具有相同的名称时(除了通过Data Contract Surrogates或其他一些过度杀伤方法完全控制序列化过程之外),没有办法做到这一点。 / p>
答案 2 :(得分:0)
我认为你的派生类还需要用[Serializable]
属性标记为可序列化/可反序列化。
除了serializable属性之外,您还需要使两者中的一个具有不同的XML名称 - 正如错误所述,在“XML world”中,它们都被称为“ClassA”。其中一个必须使用XmlElement
属性进行不同的命名(假设您正在使用XmlSerializer - 对吗?)
namespace Domain
{
[Serializable]
[XmlElement(ElementName="ClassABase")]
public class ClassA
{
public virtual int MyProperty
{
get; set;
}
}
}
namespace Derived
{
[Serializable]
public class ClassA : Domain.ClassA
{
public override int MyProperty
{
get { return 1; } set { /* Do Nothing */ }
}
}
}
马克
答案 3 :(得分:0)
为您的域设置基本命名空间,并为派生类设置自定义元素名称:
namespace Domain
{
[Serializable]
[XmlRoot(Namespace = "http://mynamespace/domain/2009/")]
public class ClassA
{
[XmlIgnore]
public virtual int MyProperty { get; set; }
}
}
namespace Derived
{
[Serializable]
[XmlRoot(ElementName = "DerivedClassA")]
public class ClassA : Domain.ClassA
{
public override int MyProperty
{
get
{
return 1;
}
set
{
base.MyProperty = value;
}
}
}
}
答案 4 :(得分:0)
我遇到了同样的问题,但有一个额外的限制:无法访问Domain或Derived类的源代码。从Domain对象继承的Derived对象,并且由于这些类具有相同的非限定名称,XmlSerializer将无法序列化Derived类的对象。
这可能已经用蛮力解决了(修改其中一个类的IL以添加适当的属性),但我想要一些“更干净”的东西。这是有效的:
var attrs = new XmlAttributes();
attrs.XmlType = new XmlTypeAttribute("anythingButClassA");
var overrides = new XmlAttributeOverrides();
overrides.Add(typeof(Domain.ClassA), attrs);
var serializer = new XmlSerializer(typeof(Derived.ClassA), overrides);
serializer.Serialize(Console.Out, new Derived.ClassA());
即使您是Domain和/或Derived类的作者,也不需要重命名它们。
答案 5 :(得分:0)
这只是提供信息,因为它没有提供具体的答案,但这是2003年7月MSDN问题讨论这些名称冲突的好文章。 "XML Namespace Collisions, XmlNodeList and Deserialization, and More"