类XML序列化具有会员延长了从抽象类型 [英] XML Serialization of Class Which Has a Member Extended From an Abstract Type

查看:96
本文介绍了类XML序列化具有会员延长了从抽象类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我碰上 InvalidOperationException异常尝试运行此code时。

为例code

 使用系统;
使用System.Collections.Generic;
使用System.IO;
使用的System.Xml.Serialization;

命名空间XMLSerializationExample
{
    类节目
    {
        静态无效的主要(字串[] args)
        {
            大篷车C =新大篷车();
            c.WriteXML();
        }
    }

    [XmlRoot(大篷车,命名空间=金塔:大篷车)]
    公共类大篷车
    {
        [的XmlElement(车辆)
        大众汽车车辆;
        公共大篷车()
        {
            车辆=新车{
                请=铃木,
                模型=雨燕,
                门= 3
            };
        }

        公共无效中WriteXML()
        {
            XmlSerializer的XS =新的XmlSerializer(typeof运算(大篷车));
            使用(的TextWriter TW =新的StreamWriter(@C:\ caravan.xml))
            {
                xs.Serialize(TW,这一点);
            }
        }
    }
    公共抽象类汽车
    {
        公共字符串做;
        公共字符串模式;
    }
    公共类汽车:汽车
    {
        公众诠释门;
    }
    公共类车:汽车
    {
        公众诠释BedLength;
    }
}
 

内部异常

  

{类型XMLSerializationExample.Car是没有预料到。使用XmlInclude或SoapInclude属性来指定不知道静态类型。}

问题

我该如何解决这个问题code?有没有别的东西,我应该做的事?

我在哪里把下面的?

  [XmlInclude(typeof运算(车))]
[XmlInclude(typeof运算(卡车))]
 

自动大篷车上面的属性类不工作。直接添加类型的的XmlSerializer 像下面的例子中不起作用,无论是。

  XmlSerializer的XS =新的XmlSerializer(typeof运算(大篷车),新类型[] {
    typeof运算(车)的typeof(卡车)});
 

解决方案

我真的不能解释为什么这是必要的,但除了加入 XmlInclude 属性,你将需要确保你的类指定一些非空的命名空间,因为你所指定的根命名空间(一个错误也许)。它不一定必须是相同的命名空间,但它必须是什么。它甚至可能是一个空字符串,它只是不能(这是默认值明显)。

这细连载:

  [XmlRoot(大篷车,命名空间=金塔:大篷车)]
公共类大篷车
{
    [的XmlElement(车辆)
    大众汽车车辆;

    // ...
}

[XmlInclude(typeof运算(车))]
[XmlInclude(typeof运算(卡车))]
[XmlRoot(自动,命名空间=)] //这使得它的工作
公共抽象类汽车
{
    [的XmlElement(使)] //不是绝对必要的,但为了一致性
    公共字符串做;
    [的XmlElement(模型)
    公共字符串模式;
}
 

I run into an InvalidOperationException when attempting to run this code.

Example Code

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;
    }
}

Inner Exception

{"The type XMLSerializationExample.Car was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically."}

Question

How do I fix this code? Is there something else that I should be doing?

Where do I put the following?

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

Putting the attributes above the Auto or the Caravan classes do not work. Adding the types directly to the XmlSerializer like the example below does not work, either.

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

解决方案

I can't really explain why this is needed but in addition to adding the XmlInclude attributes, you'll need to make sure that your classes specify some non-null namespace since you have specified a namespace on the root (a bug perhaps). It doesn't necessarily have to be the same namespace but it has to be something. It could even be an empty string, it just can't be null (which is the default value apparently).

This serializes fine:

[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;
}

这篇关于类XML序列化具有会员延长了从抽象类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆