1

クラスをXMLにシリアル化する際に問題が発生しました。エラーを表示するを実行するサンプルコードを作成しました。「ContentContainer」という名前のシリアル化するクラスであるContentContainerには、そのタイプが「ContentItemBase」であるアイテムのコレクションがあります。私の要件のため、これらのクラスを次のように実装しました。しかし、実際のシリアル化呼び出しの場合、コードがその部分に到達すると、シリアライザーはこの例外をスローします。

タイプUserQuery+SpecificContentItemは予期されていませんでした。XmlIncludeまたはSoapInclude属性を使用して、静的に認識されていないタイプを指定します。

この問題を検索しましたが、例外メッセージに記載されているXmlIncludeメソッドを実装できません。この問題および同様の問題に対する解決策(設計または実装のヒント)はありますか?

コード:

void Main()
{
    var item  = new SpecificContentItem{ Name = "Test", Value = "TestValue" , SpecificField="TestField"};
    var container = new ContentContainer();
    container.Items.Add(item);
    container.Name = "Test Container";
    XmlSerializer ser=  new XmlSerializer(typeof(ContentContainer));
    StringWriter writer = new StringWriter();
    ser.Serialize(writer, container);
    string result = writer.ToString();
}
public abstract class ContentItemBase
{
    public abstract string Name {get; set;}
    public abstract string Value {get; set;}
}

public class SpecificContentItem: ContentItemBase
{
    public string SpecificField {get; set;}
    public override string Name {get; set;}
    public override string Value {get; set;}
}
public class ContentContainer
{
    public ContentContainer()
    {
        Items = new ContentItemCollection();
    }
    public string Name {get;set;}
    public ContentItemCollection Items{get; set;}
}

public class ContentItemCollection : IEnumerable<ContentItemBase>
{
        public SpecificContentItem SpecificItem { get; set; }
        public IEnumerator<ContentItemBase> GetEnumerator()
        {
            if (SpecificItem != null)
                yield return SpecificItem;
        }
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
        public void Add(Object obj)
        {
            if (obj is SpecificContentItem)
                SpecificItem = (SpecificContentItem)obj;
        }
}
4

2 に答える 2

1

シリアライザーを次のように作成します。

XmlSerializer ser = new XmlSerializer(typeof(ContentContainer), 
                            new Type[] { typeof(SpecificContentItem) });

トリックを行う必要があります。

クラスにSerializeメソッドを追加することもできますContentContainer

public string Serialize()
{
    var types = Items.Select(x => x.GetType()).Distinct().ToArray();
    XmlSerializer ser = new XmlSerializer(typeof(ContentContainer),types);
    StringWriter writer = new StringWriter();
    ser.Serialize(writer, this);
    return writer.ToString();
}
于 2012-07-12T08:59:43.247 に答える
0

の許可された使用法XmlIncludeがあいまいなように思われるので、私はまだ提案するつもりです

[XmlInclude(typeof(SpecificContentItem))]
public class ContentItemCollection : IEnumerable<ContentItemBase>
{

可能な解決策として。それがあなたの実世界の状況にどのように当てはまるかを判断するのは少し難しいですが、それが当てはまり、うまくいくことを願っています!

于 2012-07-12T09:43:32.650 に答える