【问题标题】:Inherited Attributes and EF Code First Dynamic Proxy继承的属性和 EF Code First 动态代理
【发布时间】:2013-01-15 16:57:58
【问题描述】:

我的问题与this 问题有关。 我有一个 POCO 类,它具有从子级到父级的虚拟导航属性。父级有一组子级。

public class Parent
{
    public virtual List<Child> Children { get; set; }
}

public class Child
{
    public string ParentID { get; set; }

    [XmlIgnore]
    [ForeignKey("ParentID")]
    public virtual Parent Parent { get; set; }
}

现在...您猜对了 - 我尝试使用 XmlSerializer 序列化来自 EF(即代理)的父级。它首先抱怨我以某种方式处理的所有未知类型(动态生成的类)。但随后它会出现“循环引用”异常。

经过一番调查,原因是无法通过代理对象的 Parent 属性的反射发现 XmlIgnore 属性。

    Type.GetType("System.Data.Entity.DynamicProxies.Child_2C9351FD5E156D94E5BF2C68DABFC2A956181C99A0C2E4E6B592E6373D8645ED, EntityFrameworkDynamicProxies-Test, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
.GetProperty("Parent").GetCustomAttributes(typeof(XmlIgnoreAttribute), true) <-- returns 'None'

代理对象的类型基类型是我的子类。 XmlIgnoreAttribute 没有设置 Inherited 标志,默认值为 true,所以应该可以。发生了什么?

代理对象是否谎报其基本类型?

如何在不编写“手动”xml 序列化的情况下解决此问题(我需要使用 XmlSerializer)。

更新: 事实证明,XMLSerializer 不尊重属性的“继承性”,这似乎是错误的。这是一个错误还是设计使然?

【问题讨论】:

  • 假设您可以序列化代理。下一步你要怎么做?你将如何使用它?它可以在不同的机器上工作吗?如果您重新启动应用程序,它会起作用吗?我不记得类型名称是如何生成的,但每次启动应用程序时它可能会有所不同。此外,代理具有对不可序列化类型的引用。如果您需要序列化实体,您应该禁用代理创建。
  • 我只记得 XmlSerializer 不会序列化私有字段/属性,因此关于不可序列化的私有字段/对象的注释是错误的 - XmlSerialization 应该无关紧要。
  • @Pawel - 我只需要从代理创建 XML。我也使用其他属性——例如 XmlRootAttribute,因此 XML 看起来就像 POCO 对象已被序列化一样。顺便说一句,我已经通过实现 IXmlSerializable 解决了我的问题。不过还是很好奇这个。
  • 这就是我想要建议的 - IXmlSerializable。虽然实现起来有点痛苦(做过一次)......

标签: .net xml-serialization xmlserializer


【解决方案1】:

根据thismsdn 文章(备注部分):

'此方法忽略属性和事件的继承参数。要在继承链中搜索属性和事件的属性,请使用 Attribute.GetCustomAttributes 方法的适当重载。'

所以这不必对代理做任何事情。看看这个例子:

public class Test
{
    [XmlIgnore]
    public virtual int Property { get; set; }
}

public class Derived : Test
{
    public override int Property { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(
            typeof(Derived)
           .GetProperty("Property")
           .GetCustomAttributes(typeof(XmlIgnoreAttribute), true)
           .Count());

        Console.WriteLine(
           Attribute.GetCustomAttributes(
               typeof(Derived)
              .GetProperty("Property"), true)
              .Count());
    }
}

结果:

0
1
Press any key to continue . . .

【讨论】:

  • 我完全同意你的看法,我不确定 XMLSerializer 是否使用这种确切的方法,但我做了一个测试来序列化 Derived 对象并且属性被序列化。这意味着 XMLSerializer 无论出于何种原因都不尊重基类的属性。我更新了问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多