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

c# .net xml serialization .net-2.0

216105 просмотра

16 ответа

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

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

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

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

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

Автор: leora Источник Размещён: 17.05.2019 02:54

Ответы (16)


399 плюса

Решение

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

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

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

Автор: Lamar Размещён: 13.09.2008 02:53

108 плюса

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

Автор: Jeremy McGee Размещён: 13.09.2008 04:23

24 плюса

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

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

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

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

[XmlType("BaseNamespace.Class1")]

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

Автор: Dennis Calla Размещён: 16.09.2011 09:51

7 плюса

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

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

Автор: Rob Cooper Размещён: 13.09.2008 05:31

6 плюса

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

 - the object being serialized has no parameterless constructor
 - the object contains Dictionary
 - the object has some public Interface members
Автор: Stefan Michev Размещён: 22.02.2014 12:29

5 плюса

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

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

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

КАК: Отладить в сгенерированную сборку .NET XmlSerializer

Автор: Gulzar Nazim Размещён: 13.09.2008 03:05

5 плюса

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

Автор: Luca Размещён: 26.04.2010 06:34

4 плюса

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

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

Автор: Charlie Salts Размещён: 02.07.2009 07:32

3 плюса

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

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

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

Автор: LepardUK Размещён: 17.12.2010 02:15

2 плюса

Я тоже подумал, что атрибут 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();
        }
    }

}

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

Автор: Darren Размещён: 13.09.2008 03:23

2 плюса

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

Вместо этого можно использовать List<SomeClass>.

Автор: jkokorian Размещён: 12.01.2012 12:59

1 плюс

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

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

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

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

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

Автор: Jeremy Brown Размещён: 17.12.2012 10:22

0 плюса

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

Автор: Phil Wright Размещён: 13.09.2008 02:55

0 плюса

Я использовал этот NetDataSerialiserкласс для сериализации классов моего домена. NetDataContractSerializer Class .

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

Автор: peterka Размещён: 16.09.2008 01:14

0 плюса

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

//Или же

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

Автор: Kiran.Bakwad Размещён: 16.02.2017 11:48

0 плюса

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

Автор: Curious Dev Размещён: 26.05.2017 01:19
Вопросы из категории :
32x32