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
невозможно сериализовать абстрактные свойства.. См. мой вопрос здесь (к которому я добавил код решения)..
наиболее распространенные причины на меня:
- the object being serialized has no parameterless constructor
- the object contains Dictionary
- the object has some public Interface members
все объекты в графе сериализации должны быть сериализуемыми.
С 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 для сериализации.