【问题标题】:Virtual properties duplicated during serialization when XmlElement attribute used使用 XmlElement 属性时在序列化期间重复的虚拟属性
【发布时间】:2011-02-10 00:51:40
【问题描述】:

目标:

XML 序列化一个对象,该对象包含该对象及其派生类型的对象列表。生成的 XML 不应使用 xsi:type 属性来描述类型,因为序列化 XML 元素的名称将是特定于派生类型的分配名称,而不总是基类的名称,这是默认行为。

尝试:

在探索 IXmlSerializable 和 IXmlSerializable 与怪异的 XmlSchemaProvider 方法和巫毒反射返回专门的模式和 XmlQualifiedName 在几天的过程中,我发现我能够使用简单的 [XmlElement] 属性来实现目标......几乎。

问题:

被覆盖的属性在序列化时出现两次。异常读取“来自命名空间 '' 的 XML 元素 'overriddenProperty' 已存在于当前范围内。使用 XML 属性为元素指定另一个 XML 名称或命名空间。”我尝试使用 *Specified 属性(参见代码),但没有成功。

示例代码:

Class Declaration

using System;
using System.Collections.Generic;
using System.Xml.Serialization;

[XmlInclude(typeof(DerivedClass))]
public class BaseClass
{
    public BaseClass() { }

    [XmlAttribute("virt")]
    public virtual string Virtual
    {
        get;
        set;
    }
    [XmlIgnore]
    public bool VirtualSpecified
    {
        get { return (this is BaseClass); }
        set { }
    }

    [XmlElement(ElementName = "B", Type = typeof(BaseClass), IsNullable = false)]
    [XmlElement(ElementName = "D", Type = typeof(DerivedClass), IsNullable = false)]
    public List<BaseClass> Children
    {
        get;
        set;
    }
}

public class DerivedClass : BaseClass
{
    public DerivedClass() { }

    [XmlAttribute("virt")]
    public override string Virtual
    {
        get { return "always return spackle"; }
        set { }
    }
}

司机:

BaseClass baseClass = new BaseClass() { 
    Children = new List<BaseClass>()
};
BaseClass baseClass2 = new BaseClass(){};
DerivedClass derivedClass1 = new DerivedClass() { 
    Children = new List<BaseClass>()
};
DerivedClass derivedClass2 = new DerivedClass()
{
    Children = new List<BaseClass>()
};

baseClass.Children.Add(derivedClass1);
baseClass.Children.Add(derivedClass2);
derivedClass1.Children.Add(baseClass2);

我已经断断续续地为此苦苦挣扎了好几个星期,但在任何地方都找不到答案。

【问题讨论】:

  • 请发布生成的 XML。

标签: .net xml-serialization


【解决方案1】:

找到了。

解决方案:

使用 [XmlIgnore] 属性装饰被覆盖的属性。正确的虚值仍然是序列化的。

类声明

using System;
using System.Collections.Generic;
using System.Xml.Serialization;

[XmlInclude(typeof(DerivedClass))]
public class BaseClass
{
    public BaseClass() { }

    [XmlAttribute("virt")]
    public virtual string Virtual
    {
        get;
        set;
    }

    [XmlElement(ElementName = "B", Type = typeof(BaseClass), IsNullable = false)]
    [XmlElement(ElementName = "D", Type = typeof(DerivedClass), IsNullable = false)]
    public List<BaseClass> Children
    {
        get;
        set;
    }
}

public class DerivedClass : BaseClass
{
    public DerivedClass() { }

    [XmlAttribute("virt")]
    [XmlIgnore]
    public override string Virtual
    {
        get { return "always return spackle"; }
        set { }
    }
}

【讨论】:

  • 我使用 linq2sql,我还想在生成的文件之外“装饰”生成的类。装饰我的意思是将一些属性设置为 XmlElement,将一些设置为 XmlIgnore,一些设置为 XmlAttribute 等,以及 ev。修改他们的名字。我尝试在 PARTIAL CLASS 上使用上面的代码(与我要装饰的生成的 linq2sql 类的名称相同),但在 DerivedClass 中我收到此错误:错误 1 ​​'MyClasses.Data.DerivedClass.id.get ':无法覆盖继承的成员 'MyClasses.Data.MyObject.id.get',因为它没有标记为虚拟、抽象或覆盖。 “设置”的相同错误。想法?
  • 如果您有一个 XSD 生成的类可以在对该托管文件进行更新时自动更新,那么这是一个很好的解决方案。在迟早发生的情况下,您可以使用此方法创建一个派生的包装类作为备份。
猜你喜欢
  • 2021-05-29
  • 1970-01-01
  • 2017-04-26
  • 1970-01-01
  • 1970-01-01
  • 2021-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多