XmlSerializer - произошла ошибка, отражающая тип
216105 просмотра
16 ответа
Используя C # .NET 2.0, у меня есть составной класс данных, который имеет [Serializable]
атрибут. Я создаю XMLSerializer
класс и передаю его в конструктор:
XmlSerializer serializer = new XmlSerializer(typeof(DataClass));
Я получаю исключение, сказав:
Произошла ошибка, отражающая тип.
Внутри класса данных есть еще один составной объект. Нужно ли для этого иметь [Serializable]
атрибут, или, имея его на верхнем объекте, он рекурсивно применяет его ко всем объектам внутри?
Ответы (16)
399 плюса
Посмотрите на внутреннее исключение, которое вы получаете. Он скажет вам, какое поле / свойство имеет проблемы с сериализацией.
Вы можете исключить поля / свойства из сериализации xml, украсив их [XmlIgnore]
атрибутом.
Я не думаю, что XmlSerializer
используется [Serializable]
атрибут, поэтому я сомневаюсь, что это проблема.
108 плюса
Помните, что сериализованные классы должны иметь конструкторы по умолчанию (т.е. без параметров). Если у вас нет конструктора вообще, это нормально; но если у вас есть конструктор с параметром, вам нужно добавить и конструктор по умолчанию.
Автор: Jeremy McGee Размещён: 13.09.2008 04:2324 плюса
У меня была похожая проблема, и оказалось, что сериализатор не может различить 2 класса, которые у меня были с тем же именем (один был подклассом другого). Внутреннее исключение выглядело так:
Оба типа «BaseNamespace.Class1» и «BaseNamespace.SubNamespace.Class1» используют имя типа XML «Class1» из пространства имен ». Используйте атрибуты XML, чтобы указать уникальное имя XML и / или пространство имен для типа.
Где BaseNamespace.SubNamespace.Class1 является подклассом BaseNamespace.Class1.
Что мне нужно было сделать, это добавить атрибут в один из классов (я добавил в базовый класс):
[XmlType("BaseNamespace.Class1")]
Примечание. Если у вас есть несколько слоев классов, вам также необходимо добавить к ним атрибут.
Автор: Dennis Calla Размещён: 16.09.2011 09:517 плюса
Также имейте в виду, что XmlSerializer
не может сериализовать абстрактные свойства. Смотрите мой вопрос здесь (к которому я добавил код решения) ..
Сериализация XML и унаследованные типы
Автор: Rob Cooper Размещён: 13.09.2008 05:316 плюса
Наиболее распространенные мной причины:
- 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:055 плюса
Если вам нужно обрабатывать определенные атрибуты (например, Словарь или любой другой класс), вы можете реализовать интерфейс 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 плюса
Я обнаружил, что класс Dictionary в .Net 2.0 не сериализуем с использованием XML, но хорошо сериализуется, когда используется двоичная сериализация.
Я нашел работу вокруг здесь .
Автор: Charlie Salts Размещён: 02.07.2009 07:323 плюса
Я недавно получил это в частичном классе веб-ссылки при добавлении нового свойства. Сгенерированный автоматически класс добавляет следующие атрибуты.
[System.Xml.Serialization.XmlElementAttribute(Order = XX)]
Мне нужно было добавить аналогичный атрибут с порядком на один выше, чем последний в автоматически сгенерированной последовательности, и это исправило это для меня.
Автор: LepardUK Размещён: 17.12.2010 02:152 плюса
Я тоже подумал, что атрибут 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:232 плюса
Я просто получил ту же ошибку и обнаружил, что IEnumerable<SomeClass>
проблема связана со свойством типа . Похоже, что IEnumerable
не может быть сериализовано напрямую.
Вместо этого можно использовать List<SomeClass>
.
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:220 плюса
Также обратите внимание, что вы не можете сериализовать элементы управления пользовательского интерфейса и что любой объект, который вы хотите передать в буфер обмена, должен быть сериализуемым, иначе он не может быть передан другим процессам.
Автор: Phil Wright Размещён: 13.09.2008 02:550 плюса
Я использовал этот NetDataSerialiser
класс для сериализации классов моего домена. NetDataContractSerializer Class .
Классы домена распределяются между клиентом и сервером.
Автор: peterka Размещён: 16.09.2008 01:140 плюса
[System.Xml.Serialization.XmlElementAttribute ("strFieldName", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
//Или же
[XmlIgnore] string [] strFielsName {get; set;}
Автор: Kiran.Bakwad Размещён: 16.02.2017 11:480 плюса
У меня была та же проблема, и в моем случае объект имел ReadOnlyCollection. Коллекция должна реализовывать метод Add для сериализации.
Автор: Curious Dev Размещён: 26.05.2017 01:19Вопросы из категории :
- c# Преобразовать десятичную в двойную?
- c# Как рассчитать чей-то возраст в C #?
- c# Как вы сортируете словарь по значению?
- c# В чем разница между int и Integer в Java и C #?
- .net Как создать новый экземпляр объекта из Типа
- .net Действительно ли опечатанные классы действительно предлагают преимущества?
- xml Обработка XML в Python
- xml Каков наилучший способ проверки XML-файла по сравнению с XSD-файлом?
- xml Removing nodes from an XmlDocument
- xml Как анализировать XML-файлы?
- serialization Могу ли я сериализовать объект типа C #?
- serialization XmlSerializer - произошла ошибка, отражающая тип
- serialization Самые большие различия между Thrift и Protocol Buffers?
- serialization Как вы делаете глубокую копию объекта в .NET (C # конкретно)?
- .net-2.0 CLR Profiler - Присоединение к существующему процессу
- .net-2.0 «Невозможно изменить тип DataType столбца после его получения» в Visual Studio 2005 DataSet Designer
- .net-2.0 Лучший способ запутать или защитить сборки .Net