当前位置:  开发笔记 > 编程语言 > 正文

XmlSerializer - 反映类型时出错

如何解决《XmlSerializer-反映类型时出错》经验,为你挑选了7个好方法。

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

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

我得到一个例外说:

有一个反映类型的错误.

在数据类内部还有另一个复合对象.这是否还需要具有该[Serializable]属性,或者将其置于顶层对象上,是否以递归方式将其应用于内部的所有对象?



1> Lamar..:

看看你得到的内在异常.它将告诉您序列化时遇到问题的字段/属性.

您可以通过使用[XmlIgnore]属性进行装饰来从xml序列化中排除字段/ 属性.

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


谢谢,这个答案帮助了我.我最初看了一下内部异常,刚看到提到主类.但是我意识到我可以深入研究这些不确定因素,并最终降低5级,我发现了这个问题.我的课程相互矛盾.谢谢.
我的对象有一个Uri字段,导致了这个异常; Uri类没有无参数构造函数.谢谢你的提示.
通过谷歌搜索遇到了这个 - 我的特殊问题是当我需要"List"时,我的"被序列化"类中的属性为"IList".
如何看待"内部异常"?
或者将"@exception"添加到手表中
@David:try {...} catch(Exception e){Exception ie = e.InnerException}

2> Jeremy McGee..:

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


感谢您的提醒!我讨厌这是一个运行时错误,几乎没有解释.

3> 小智..:

我遇到了类似的问题,结果发现序列化程序无法区分我使用相同名称的两个类(一个是另一个类的子类).内部异常看起来像这样:

'Types BaseNamespace.Class1'和'BaseNamespace.SubNamespace.Class1'都使用来自命名空间''的XML类型名称'Class1'.使用XML属性为类型指定唯一的XML名称和/或命名空间.

其中BaseNamespace.SubNamespace.Class1是BaseNamespace.Class1的子类.

我需要做的是为其中一个类添加一个属性(我添加到基类):

[XmlType("BaseNamespace.Class1")]

注意:如果您有更多层类,则还需要为它们添加属性.



4> Rob Cooper..:

另外请注意,XmlSerializer不能序列化抽象属性..请在这里查看我的问题(我已经添加了解决方案代码)..

XML序列化和继承类型



5> Stefan Miche..:

我最常见的原因:

 - the object being serialized has no parameterless constructor
 - the object contains Dictionary
 - the object has some public Interface members



6> Gulzar Nazim..:

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

由于XMLSerializer是黑盒子,如果要进一步调试序列化过程,请检查这些链接.

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

HOW TO:调试到.NET XmlSerializer生成的程序集



7> Luca..:

如果您需要处理特定属性(即Dictionary或任何类),您可以实现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
}

有一篇有趣的文章,展示了一种实现"扩展"XmlSerializer的复杂方法的优雅方法.


文章说:

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

因为这个,我建议你实现自己的IXmlSerializable类,以避免过多的复杂实现.

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

推荐阅读
谢谢巷议
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有