C# XmlSerializer - 有一个错误反映类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/60573/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 10:19:12  来源:igfitidea点击:

XmlSerializer - There was an error reflecting type

提问by leora

Using C# .NET 2.0, I have a composite data class that does have the [Serializable]attribute on it. I am creating an XMLSerializerclass and passing that into the constructor:

使用 C# .NET 2.0,我有一个复合数据类,它确实具有该[Serializable]属性。我正在创建一个XMLSerializer类并将其传递给构造函数:

XmlSerializer serializer = new XmlSerializer(typeof(DataClass));

I am getting an exception saying:

我收到一个异常说:

There was an error reflecting type.

存在错误反映类型。

Inside the data class there is another composite object. Does this also need to have the [Serializable]attribute, or by having it on the top object, does it recursively apply it to all objects inside?

在数据类中还有另一个复合对象。这是否也需要具有[Serializable]属性,或者通过将其放在顶部对象上,是否将其递归应用于内部的所有对象?

采纳答案by Lamar

Look at the inner exception that you are getting. It will tell you which field/property it is having trouble serializing.

看看你得到的内部异常。它会告诉您序列化遇到问题的字段/属性。

You can exclude fields/properties from xml serialization by decorating them with the [XmlIgnore]attribute.

您可以通过使用[XmlIgnore]属性修饰字段/属性来从 xml 序列化中排除它们。

XmlSerializerdoes not use the [Serializable]attribute, so I doubt that is the problem.

XmlSerializer不使用该[Serializable]属性,所以我怀疑这是问题所在。

回答by Phil Wright

Also note that you cannot serialize user interface controls and that any object you want to pass onto the clipboard must be serializable otherwise it cannot be passed across to other processes.

另请注意,您无法序列化用户界面控件,并且您要传递到剪贴板的任何对象都必须是可序列化的,否则无法将其传递给其他进程。

回答by Gulzar Nazim

All the objects in the serialization graph have to be serializable.

序列化图中的所有对象都必须是可序列化的。

Since XMLSerializeris a blackbox, check these links if you want to debug further into the serialization process..

由于XMLSerializer是一个黑盒,如果您想进一步调试序列化过程,请检查这些链接。

Changing where XmlSerializer Outputs Temporary Assemblies

更改 XmlSerializer 输出临时程序集的位置

HOW TO: Debug into a .NET XmlSerializer Generated Assembly

如何:调试到 .NET XmlSerializer 生成的程序集

回答by Darren

I too thought that the Serializable attribute had to be on the object but unless I'm being a complete noob (I am in the middle of a late night coding session) the following works from the SnippetCompiler:

我也认为 Serializable 属性必须在对象上,但除非我是一个完整的菜鸟(我正处于深夜编码会话的中间),否则SnippetCompiler的以下工作:

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

public class Inner
{
    private string _AnotherStringProperty;
    public string AnotherStringProperty 
    { 
      get { return _AnotherStringProperty; } 
      set { _AnotherStringProperty = value; } 
    }
}

public class DataClass
{
    private string _StringProperty;
    public string StringProperty 
    { 
       get { return _StringProperty; } 
       set{ _StringProperty = value; } 
    }

    private Inner _InnerObject;
    public Inner InnerObject 
    { 
       get { return _InnerObject; } 
       set { _InnerObject = value; } 
    }
}

public class MyClass
{

    public static void Main()
    {
        try
        {
            XmlSerializer serializer = new XmlSerializer(typeof(DataClass));
            TextWriter writer = new StreamWriter(@"c:\tmp\dataClass.xml");
            DataClass clazz = new DataClass();
            Inner inner = new Inner();
            inner.AnotherStringProperty = "Foo2";
            clazz.InnerObject = inner;
            clazz.StringProperty = "foo";
            serializer.Serialize(writer, clazz);
        }
        finally
        {
            Console.Write("Press any key to continue...");
            Console.ReadKey();
        }
    }

}

I would imagine that the XmlSerializer is using reflection over the public properties.

我会想象 XmlSerializer 正在对公共属性使用反射。

回答by Jeremy McGee

Remember that serialized classes must have default (i.e. parameterless) constructors. If you have no constructor at all, that's fine; but if you have a constructor with a parameter, you'll need to add the default one too.

请记住,序列化类必须具有默认(即无参数)构造函数。如果您根本没有构造函数,那也没关系;但是如果你有一个带参数的构造函数,你也需要添加默认的。

回答by Rob Cooper

Also be aware that XmlSerializercannot serialize abstract properties.. See my question here(which I have added the solution code to)..

另请注意,XmlSerializer无法序列化抽象属性.. 请参阅我的问题here(我已将解决方案代码添加到其中)。

XML Serialization and Inherited Types

XML 序列化和继承类型

回答by Rob Cooper

I have been using the NetDataSerialiserclass to serialise my domain classes. NetDataContractSerializer Class.

我一直在使用NetDataSerialiser该类来序列化我的域类。NetDataContractSerializer 类

The domain classes are shared between client and server.

域类在客户端和服务器之间共享。

回答by Charlie Salts

I've discovered that the Dictionary class in .Net 2.0 is not serializable using XML, but serializes well when binary serialization is used.

我发现 .Net 2.0 中的 Dictionary 类不能使用 XML 进行序列化,但是在使用二进制序列化时可以很好地序列化。

I found a work around here.

我在这里找到了一份工作。

回答by Luca

If you need to handle specific attributes (i.e. Dictionary, or any class), you can implement the IXmlSerialiableinterface, which will allow you more freedom at the cost of more verbose coding.

如果您需要处理特定的属性(即字典或任何类),您可以实现IXmlSerialiable接口,这将允许您以更详细的编码为代价获得更多的自由。

public class NetService : IXmlSerializable
{
    #region Data

        public string Identifier = String.Empty;

        public string Name = String.Empty;

        public IPAddress Address = IPAddress.None;
        public int Port = 7777;

    #endregion

    #region IXmlSerializable Implementation

        public XmlSchema GetSchema() { return (null); }

        public void ReadXml(XmlReader reader)
        {
            // Attributes
            Identifier = reader[XML_IDENTIFIER];
            if (Int32.TryParse(reader[XML_NETWORK_PORT], out Port) == false)
            throw new XmlException("unable to parse the element " + typeof(NetService).Name + " (badly formatted parameter " + XML_NETWORK_PORT);
            if (IPAddress.TryParse(reader[XML_NETWORK_ADDR], out Address) == false)
            throw new XmlException("unable to parse the element " + typeof(NetService).Name + " (badly formatted parameter " + XML_NETWORK_ADDR);
        }

        public void WriteXml(XmlWriter writer)
        {
            // Attributes
            writer.WriteAttributeString(XML_IDENTIFIER, Identifier);
            writer.WriteAttributeString(XML_NETWORK_ADDR, Address.ToString());
            writer.WriteAttributeString(XML_NETWORK_PORT, Port.ToString());
        }

        private const string XML_IDENTIFIER = "Id";

        private const string XML_NETWORK_ADDR = "Address";

        private const string XML_NETWORK_PORT = "Port";

    #endregion
}

There is an interesting article, which show an elegant way to implements a sophisticated way to "extend" the XmlSerializer.

有一篇有趣的文章,它展示了一种优雅的方式来实现“扩展” XmlSerializer 的复杂方式。



The article say:

文章说:

IXmlSerializable is covered in the official documentation, but the documentation states it's not intended for public use and provides no information beyond that. This indicates that the development team wanted to reserve the right to modify, disable, or even completely remove this extensibility hook down the road. However, as long as you're willing to accept this uncertainty and deal with possible changes in the future, there's no reason whatsoever you can't take advantage of it.

IXmlSerializable 包含在官方文档中,但文档声明它不适合公共使用,并且没有提供除此之外的任何信息。这表明开发团队希望保留修改、禁用甚至完全删除此可扩展性挂钩的权利。但是,只要您愿意接受这种不确定性并应对未来可能发生的变化,就没有任何理由不能利用它。

Because this, I suggest to implement you're own IXmlSerializableclasses, in order to avoid too much complicated implementations.

正因为如此,我建议实现你自己的IXmlSerializable类,以避免太多复杂的实现。

...it could be straightforward to implements our custom XmlSerializerclass using reflection.

...XmlSerializer使用反射实现我们的自定义类可能很简单。

回答by LepardUK

I recently got this in a web reference partial class when adding a new property. The auto generated class was adding the following attributes.

我最近在添加新属性时在 Web 参考部分类中得到了这个。自动生成的类添加了以下属性。

    [System.Xml.Serialization.XmlElementAttribute(Order = XX)]

I needed to add a similar attribute with an order one higher than the last in the auto generated sequence and this fixed it for me.

我需要添加一个类似的属性,其顺序比自动生成的序列中的最后一个高,这为我修复了它。