0

InvalidOperationExceptionこのコードを実行しようとすると、エラーが発生します。

サンプルコード

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;

namespace XMLSerializationExample
{
    class Program
    {
        static void Main(string[] args)
        {
            Caravan c = new Caravan();
            c.WriteXML();
        }
    }

    [XmlRoot("caravan", Namespace="urn:caravan")]
    public class Caravan
    {
        [XmlElement("vehicle")]
        public Auto Vehicle;
        public Caravan()
        {
            Vehicle = new Car {
                Make = "Suzuki",
                Model = "Swift",
                Doors = 3
            };
        }

        public void WriteXML()
        {
            XmlSerializer xs = new XmlSerializer(typeof(Caravan));
            using (TextWriter tw = new StreamWriter(@"C:\caravan.xml"))
            {
                xs.Serialize(tw, this);
            }
        }
    }
    public abstract class Auto
    {
        public string Make;
        public string Model;
    }
    public class Car : Auto
    {
        public int Doors;
    }
    public class Truck : Auto
    {
        public int BedLength;
    }
}

内部例外

{"型 XMLSerializationExample.Car は予期されていませんでした。XmlInclude または SoapInclude 属性を使用して、静的に認識されていない型を指定してください。"}

質問

このコードを修正するにはどうすればよいですか? 他にすべきことはありますか?

次のものはどこに置くのですか?

[XmlInclude(typeof(Car))]
[XmlInclude(typeof(Truck))]

Autoまたはクラスの上に属性を配置Caravanしても機能しません。以下の例のようにタイプを直接追加してXmlSerializerも機能しません。

XmlSerializer xs = new XmlSerializer(typeof(Caravan), new Type[] {
    typeof(Car), typeof(Truck) });
4

1 に答える 1

2

なぜこれが必要なのかは説明できませんが、XmlInclude属性を追加することに加えて、ルートで名前空間を指定しているため、クラスが null 以外の名前空間を指定していることを確認する必要があります (バグの可能性があります)。必ずしも同じ名前空間である必要はありませんが、何かでなければなりません。空の文字列である可能性もありますが、そうではありませんnull(これは明らかにデフォルト値です)。

これはうまくシリアライズされます:

[XmlRoot("caravan", Namespace="urn:caravan")]
public class Caravan
{
    [XmlElement("vehicle")]
    public Auto Vehicle;

    //...
}

[XmlInclude(typeof(Car))]
[XmlInclude(typeof(Truck))]
[XmlRoot("auto", Namespace="")] // this makes it work
public abstract class Auto
{
    [XmlElement("make")] // not absolutely necessary but for consistency
    public string Make;
    [XmlElement("model")]
    public string Model;
}
于 2012-04-19T21:57:26.160 に答える