【问题标题】:How to use XMLSerializer with a Castle ActiveRecord containing an IList<T> member如何将 XMLSerializer 与包含 IList<T> 成员的 Castle ActiveRecord 一起使用
【发布时间】:2009-04-15 18:34:33
【问题描述】:

我正在尝试将 XMLSerializer 与如下所示的城堡活动记录类一起使用:

[ActiveRecord("Model")]
public class DataModel : ActiveRecordBase
{
    private IList<Document> documents;

    [XmlArray("Documents")]
    public virtual IList<Document> Documents
    {
        get { return documents; }
        set
        {
            documents = value;    
        }
    }
}

但是,由于 IList 接口,XMLSerializer 遇到了麻烦。 (引发异常:无法序列化类型为“System.Collections.Generic.IList`1...”的成员“DataModel.Documents”......

我在其他地方读到这是 XMLSerializer 的一个限制,建议的解决方法是将其声明为 List&lt;T&gt; 接口。

因此我尝试将IList&lt;Document&gt; 更改为List&lt;Document&gt;。 这会导致 ActiveRecord 引发异常: 属性 DataModel.Documents 的类型必须是一个接口(IList、ISet、IDictionary 或它们的通用计数器部分)。您不能使用 ArrayList 或 List 作为属性类型。

所以,问题是:如何将 XMLSerializer 与包含 IList 成员的 Castle ActiveRecord 一起使用?

【问题讨论】:

    标签: .net xml-serialization castle-activerecord generic-list


    【解决方案1】:

    有趣...我能建议的最好的方法是在Documents 上使用[XmlIgnore] - ActiveRecord 是否有类似的忽略成员的方式?你可以这样做:

    [XmlIgnore]
    public virtual IList<Document> Documents
    {
        get { return documents; }
        set
        {
            documents = value;    
        }
    }
    
    [Tell ActiveRecord to ignore this one...]
    [XmlArray("Documents"), XmlArrayItem("Document")]
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
    public Document[] DocumentsSerialization {
        get {
             if(Documents==null) return null;
             return Documents.ToArray(); // LINQ; or do the long way
        }
        set {
             if(value == null) { Documents = null;}
             else { Documents = new List<Document>(value); }
        }
    }
    

    【讨论】:

    • 谢谢,它有效。由于额外的属性,接口变得有点污染,但除非微软对 IList 序列化问题采取一些措施,否则我真的看不到太多选择。
    • 我读到这不是一个错误,而是一个特性,解决它的方法是使用数据传输对象(或 DTO)。
    【解决方案2】:

    Microsoft won't implement this,所以你必须解决它。一种方法是使用非泛型 IList:

    [ActiveRecord("Model")]
    public class DataModel : ActiveRecordBase<DataModel> {
        [XmlArray("Documents")]
        [HasMany(typeof(Document)]
        public virtual IList Documents {get;set;}
    }
    

    Here 提供有关此错误的更多信息。

    【讨论】:

    • 感谢您将我指向 Microsoft 错误报告。他们没有解决这个问题真的很糟糕。不过,我不想失去使用泛型列表的类型安全优势,所以我必须要么采用上面 Marc 建议的解决方案,要么将所有内容转移到 DataContractSerializer。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多