在非序列化方法上对非序列化对象进行XML序列化时出错

时间:2015-01-07 13:25:22

标签: c# xml serialization

我正在使用此代码

XmlSerializer xs = new XmlSerializer(typeof(T));

序列化对象。

现在我在这行代码中遇到错误(在嵌入式对象中以嵌套的方式对齐)

public override List<BrokenRule> GetBrokenRules() {

错误是 Csla.Validation.BrokenRule无法序列化,因为它没有无参数构造函数。

现在这是正确的,但我认为methods没有序列化,所以问题是什么(Csla.Validation.BrokenRule未在别处使用)

如果是设计,这种行为,有没有办法让运行时说“忽略对象的这一部分”?

不允许使用属性等编辑对象代码....

1 个答案:

答案 0 :(得分:1)

将此类序列化为XML的一种方法是为派生类创建XmlSerializer并传递XmlAttributeOverrides,指定返回类的属性为XmlIgnore。但是,正如documentation中所述,您必须缓存并重新使用此XmlSerializer

  

为了提高性能,XML序列化基础结构动态生成程序集以序列化和反序列化指定的类型。基础结构查找并重用这些程序集。仅当使用以下构造函数时才会出现此问题:

     

XmlSerializer.XmlSerializer(类型):

     

XmlSerializer.XmlSerializer(Type,String)

     

如果使用任何其他构造函数,则会生成同一程序集的多个版本,并且永远不会卸载,这会导致内存泄漏和性能下降。最简单的解决方案是使用前面提到的两个构造函数之一。否则,必须将程序集缓存在Hashtable中,如以下示例所示。

而不是HashTable,在简单的情况下,我将在静态构造函数中为我需要序列化的类构造我的XmlSerializer。这是相当懒惰的,并保证是线程安全的。因此,例如:

public class NoParameterlessConstructor
{
    public string Value { get; set; }

    public NoParameterlessConstructor(string value)
    {
        this.Value = value;
    }
}

public class BaseClass
{
    public NoParameterlessConstructor NoParameterlessConstructor { get; set; }
}

public class DerivedClass : BaseClass
{
    static XmlSerializer serializer = null;

    static DerivedClass()
    {
        var xOver = new XmlAttributeOverrides();
        var attrs = new XmlAttributes() { XmlIgnore = true };
        xOver.Add(typeof(BaseClass), "NoParameterlessConstructor", attrs); // Must use BaseClass here not DerivedClass!

        serializer = new XmlSerializer(typeof(DerivedClass), xOver);
    }

    public static XmlSerializer DerivedClassXmlSerializer { get { return serializer; } }

    public int Id { get; set; }
}

然后,测试:

public static class TestNoParameterlessConstructor
{
    public static void Test()
    {
        var derived = new DerivedClass { Id = 1, NoParameterlessConstructor = new NoParameterlessConstructor("Test") };
        var xml = XmlSerializationHelper.GetXml(derived, DerivedClass.DerivedClassXmlSerializer);
        Debug.WriteLine(xml);
    }
}

输出

<?xml version="1.0" encoding="utf-16"?>
<DerivedClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Id>1</Id>
</DerivedClass>