XmlSerializer - произошла ошибка, отражающая тип

используя C# .NET 2.0, у меня есть составной класс данных, который имеет

16 ответов


смотреть на внутреннее исключение, которое вы получаете. Он скажет вам, какое поле / свойство имеет проблемы с сериализацией.

вы можете исключить поля / свойства из сериализации xml, украсив их .

Я так не думаю XmlSerializer использует [Serializable] атрибут, поэтому я сомневаюсь, что это проблема.


помните, что сериализованные классы должны иметь конструкторы по умолчанию (т. е. без параметров). Если у вас нет конструктора вообще, это нормально; но если у вас есть конструктор с параметром, вам также нужно добавить конструктор по умолчанию.


У меня была похожая проблема, и оказалось, что сериализатор не может различать 2 класса у меня были с тем же именем (один был подклассом другого). Внутреннее исключение выглядело так:

' Типы BaseNamespace.Class1 " и " BaseNamespace.Подпространство.Class1 'оба используют имя типа XML "Class1" из пространства имен ". Используйте атрибуты XML для указания уникального имени XML и/или пространства имен для типа.

Где BaseNamespace.Подпространство.Класс1-это подкласс BaseNamespace.Класс1.

Мне нужно было добавить атрибут в один из классов (я добавил в базовый класс):

[XmlType("BaseNamespace.Class1")]

Примечание: Если у вас больше слоев, классов, вам необходимо добавить атрибут к ним.


также имейте в виду, что XmlSerializer невозможно сериализовать абстрактные свойства.. См. мой вопрос здесь (к которому я добавил код решения)..

сериализация XML и унаследованные типы


наиболее распространенные причины на меня:

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

все объекты в графе сериализации должны быть сериализуемыми.

С XMLSerializer является черным ящиком, проверьте эти ссылки, если вы хотите отлаживать дальше в процесс сериализации..

изменение того, где XmlSerializer выводит временные сборки

как: отладка в .NET XmlSerializer сгенерированной сборки


Если вам нужно обрабатывать определенные атрибуты (например, словарь или любой класс), вы можете реализовать 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 класс с использованием отражения.


Я обнаружил, что класс Dictionary в .Net 2.0 не сериализуется с помощью XML, но сериализуется хорошо, когда используется двоичная сериализация.

с здесь.


недавно я получил это в частичном классе веб-ссылки при добавлении нового свойства. Автоматически созданный класс добавлял следующие атрибуты.

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

Мне нужно было добавить аналогичный атрибут с порядком выше последнего в автоматически сгенерированной последовательности, и это исправило его для меня.


Я тоже думал, что сериализуемый атрибут должен быть на объекте, но если я не являюсь полным noob (я нахожусь в середине ночного сеанса кодирования), следующие работы из 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();
        }
    }

}

Я бы предположил, что XmlSerializer использует отражение через открытые свойства.


у меня была ситуация, когда порядок был одинаковым для двух элементов подряд

[System.Xml.Serialization.XmlElementAttribute(IsNullable = true, Order = 0, ElementName = "SeriousInjuryFlag")]

.... некоторый код. ..

[System.Xml.Serialization.XmlElementAttribute(IsNullable = true, Order = 0, ElementName = "AccidentFlag")]

когда я изменил код, чтобы увеличить порядок на единицу для каждого нового свойства в классе, ошибки ушли.


Я только что получил ту же ошибку и обнаружил, что свойство типа IEnumerable<SomeClass> была проблема. Оказывается, что IEnumerable нельзя сериализовать напрямую.


также обратите внимание, что вы не можете сериализовать элементы управления пользовательского интерфейса и что любой объект, который вы хотите передать в буфер обмена, должен быть сериализуемым, иначе он не может быть передан другим процессам.


Я использую NetDataSerialiser класс, чтобы serialise мои доменные классы. Класс NetDataContractSerializer.

классы домена разделены между клиентом и сервером.


[системы.XML.Сериализация.XmlElementAttribute ("strFieldName", форма = система.XML.Схема.XmlSchemaForm.Безоговорочно)]

//или

[XmlIgnore] string [] strFielsName {get;set;}


У меня была та же проблема, и в моем случае объект имел ReadOnlyCollection. Коллекция должна реализовать метод Add для сериализации.