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

Используя С#.NET 2.0, у меня есть составной класс данных, у которого есть атрибут [Serializable]. Я создаю класс XMLSerializer и передаю его в конструктор:

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

Я получаю исключение:

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

Внутри класса данных есть еще один составной объект. Должен ли это также иметь атрибут [Serializable] или его наличие на верхнем объекте, он рекурсивно применяет его ко всем объектам внутри?

294
задан 13 сент. '08 в 17:40
источник поделиться
16 ответов

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

Вы можете исключить поля/свойства из сериализации XML, украсив их атрибутом [XmlIgnore].

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

374
ответ дан 13 сент. '08 в 17:53
источник

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

104
ответ дан 13 сент. '08 в 19:23
источник

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

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

Где BaseNamespace.SubNamespace.Class1 является подклассом BaseNamespace.Class1.

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

[XmlType("BaseNamespace.Class1")]

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

20
ответ дан 17 сент. '11 в 0:51
источник

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

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

6
ответ дан 13 сент. '08 в 20:31
источник

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

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

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

КАК: Отлаживать сборку .NET XmlSerializer

5
ответ дан 13 сент. '08 в 18:05
источник

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

Я нашел работу здесь.

4
ответ дан 02 июля '09 в 22:32
источник

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

 - the object being serialized has no parameterless constructor
 - the object contains Dictionary
 - the object has some public Interface members
4
ответ дан 22 февр. '14 в 15:29
источник

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

4
ответ дан 26 апр. '10 в 21:34
источник

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

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

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

3
ответ дан 17 дек. '10 в 17:15
источник

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

2
ответ дан 13 сент. '08 в 18:23
источник

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

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

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

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

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

1
ответ дан 18 дек. '12 в 1:22
источник

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

1
ответ дан 12 янв. '12 в 15:59
источник

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

0
ответ дан 26 мая '17 в 4:19
источник

[System.Xml.Serialization.XmlElementAttribute( "strFieldName", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]

//Или

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

0
ответ дан 16 февр. '17 в 14:48
источник

Я использую класс NetDataSerialiser для сериализации мои классы домена. класс NetDataContractSerializer.

Классы домена совместно используются клиентом и сервером.

0
ответ дан 16 сент. '08 в 16:14
источник

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

0
ответ дан 13 сент. '08 в 17:55
источник

Другие вопросы по меткам или Задайте вопрос