【问题标题】:Can I dynamically apply XmlIgnore to properties of an ArrayItem?我可以动态地将 XmlIgnore 应用于 ArrayItem 的属性吗?
【发布时间】:2011-11-11 05:39:29
【问题描述】:

我正在尝试序列化一个 List,其中 T: EntityObject 并希望从列表中的项目中省略所有 EntityKey 和其他 EntityReference 属性。这可以使用 XmlAttributeOverrides 动态完成吗?

据我所知,XmlAttributeOverrides 选项仅真正指向顶级对象,即 List 而不是 T 本身,这对我没有多大帮助。 谁能指出我动态忽略 ArrayItems 属性的方法?

这是我一直在使用的一个简单示例,它不使用 EntityObjects,但它应该说明我想要做什么:

    public class Car
    {
        public String Make { get; set; }
        public String Model { get; set; }
        public Double EngineSize { get; set; }
    }

    [Test]
    public void WouldLoveToDynamicallyLeaveOutMembersOfArrayItems()
    {
        var cars = new List<Car>
                       {
                         new Car
                             {
                                 Make = "Ferrari",
                                 Model = "F1",
                                 EngineSize = 6000
                             },
                         new Car
                             {
                                 Make = "Williams",
                                 Model = "F1",
                                 EngineSize = 5500
                             }
                     };


        var attributeOverrides = new XmlAttributeOverrides();
        attributeOverrides.Add(typeof(Double), "EngineSize", new XmlAttributes {XmlIgnore = true});

        var xs = new XmlSerializer(cars.GetType(), attributeOverrides, new []{ typeof(Car) }, new XmlRootAttribute("cars"), "");
        var ms = new MemoryStream();
        xs.Serialize(ms, cars);
        ms.Position = 0;

        var sr = new StreamReader(ms);
        var result = sr.ReadToEnd();

        Assert.IsFalse(result.Contains("EngineSize"));

    }

【问题讨论】:

    标签: c# .net xml-serialization


    【解决方案1】:

    是的,您可以这样做 - 主要错误是您需要 typeof(Car) 而不是 typeof(double)。有了这个,请注意 XmlAttributeOverrides 不只适用于顶级 onject。

    但是,我不确定这是最简单的路线。首先,请注意您必须在使用 XmlAttributeOverrides 时存储和重复使用序列化程序,否则会泄漏程序集。

    我预计您想要这样做的主要原因是因为您不想编辑他生成的文件。但是,还有另一种方法;在单独的文件中,在正确的命名空间中,您可以使用:

    partial class Car {
        public bool ShouldSerializeEngineSize() { return false; }
    }
    

    其中“ShouldSerialize*”是 XmlSerializer 识别并用于控制条件序列化的模式。 “部分”类只是将两个单独的代码文件组合成一个类型的一种方式(并且是为这种生成内容场景而设计的)。

    这样,你就不需要弄乱 XmlAttributeOverrides,你可以使用更简单的“new XmlSeralizer(Type)”(每个类型都有自动缓存)。

    【讨论】:

    • 谢谢马克。试图保持 DRY 因此希望避免使用“ShouldSerialize*”选项,但也担心存储大量序列化程序集/序列化程序。在您的脑海中,您能说出任何现成的 Xml 序列化程序,它们可以很好地完成不创建序列化程序集的动态配置吗? TIA。
    • 只要您忽略数据属性,这似乎有效,但忽略 EntityKey 属性将不起作用。事实上,我为数据属性和 EntityKey 放入了两个 ShouldSerialize* 方法,并逐步通过调试器。 ShouldSerializeEntityKey 甚至不会被调用,但另一个 ShouldSerialize 会!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-02
    • 2014-06-10
    • 2015-03-10
    • 2019-03-06
    • 2011-08-28
    • 1970-01-01
    • 2019-01-09
    相关资源
    最近更新 更多