C #.NET 2.0을 사용하면 복합 데이터 클래스가[Serializable]
그것에 대한 속성. 나는XMLSerializer
클래스를 생성자에 전달합니다.
XmlSerializer serializer = new XmlSerializer(typeof(DataClass));
나는 예외를 말하고있다 :
유형을 반영하는 중에 오류가 발생했습니다.
데이터 클래스에는 또 다른 복합 객체가 있습니다. 이것도 필요합니다[Serializable]
애트리뷰트를 사용하거나 맨 위 오브젝트에 배치하여 내부의 모든 오브젝트에 재귀 적으로 적용합니까?
당신이 얻는 내부 예외를 보라. 직렬화에 문제가있는 필드 / 속성을 알려줍니다.
xml serialization에서 필드 / 속성을 제외시킬 수 있습니다.[XmlIgnore]
속성.
나는 그렇게 생각하지 않는다.XmlSerializer
~을 사용하다[Serializable]
속성, 그래서 그게 문제가 의심.
직렬화 된 클래스에는 기본 (즉, 매개 변수없는) 생성자가 있어야합니다. 생성자가 전혀 없다면 괜찮습니다. 그러나 매개 변수가있는 생성자가있는 경우 기본 매개 변수도 추가해야합니다.
비슷한 문제가 있었는데 serializer가 동일한 이름을 가진 두 클래스 (하나는 다른 클래스의 서브 클래스)를 구분할 수 없다는 것이 밝혀졌습니다. 내부 예외는 다음과 같습니다.
'Types BaseNamespace.Class1'과 'BaseNamespace.SubNamespace.Class1'모두 네임 스페이스 ''에서 XML 형식 이름 'Class1'을 사용합니다. XML 속성을 사용하여 유형에 고유 한 XML 이름 및 / 또는 네임 스페이스를 지정하십시오.
여기서 BaseNamespace.SubNamespace.Class1은 BaseNamespace.Class1의 하위 클래스입니다.
내가해야 할 일은 클래스 중 하나에 속성을 추가하는 것입니다 (기본 클래스에 추가했습니다).
[XmlType("BaseNamespace.Class1")]
참고 : 클래스의 레이어가 더 많은 경우 속성을 추가해야합니다.
나에 대한 가장 일반적인 이유 :
- 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
반사를 사용하는 클래스입니다.
.NET 2.0의 Dictionary 클래스는 XML을 사용하여 직렬화 할 수 없지만 이진 직렬화를 사용하면 잘 직렬화된다는 사실을 발견했습니다.
나는 주변에서 일을 발견했다.이리.
나는 최근에 새 속성을 추가 할 때 웹 참조 부분 클래스에서 이것을 얻었습니다. 자동 생성 클래스가 다음 속성을 추가했습니다.
[System.Xml.Serialization.XmlElementAttribute(Order = XX)]
나는 자동 생성 된 시퀀스에서 마지막 것보다 높은 순서로 비슷한 속성을 추가 할 필요가 있었고 이것으로 나를 고정시켰다.
나는 또한 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가 공용 속성에 대한 리플렉션을 사용하고 있다고 생각합니다.
방금 같은 오류가 발생하여 유형의 속성을 발견했습니다.IEnumerable<SomeClass>
문제였다. 그것은 나타난다.IEnumerable
직접 직렬화 할 수 없습니다.
주문이 연속적으로 두 요소에 대해 동일했던 상황이있었습니다.
[System.Xml.Serialization.XmlElementAttribute(IsNullable = true, Order = 0, ElementName = "SeriousInjuryFlag")]
.... 일부 코드 ...
[System.Xml.Serialization.XmlElementAttribute(IsNullable = true, Order = 0, ElementName = "AccidentFlag")]
클래스의 각 새 Property에 대해 순서를 하나씩 늘리도록 코드를 변경하면 오류가 사라집니다.
또한 사용자 인터페이스 컨트롤을 직렬화 할 수 없으며 클립 보드에 전달할 객체는 직렬화 가능해야하며 그렇지 않으면 다른 프로세스로 전달할 수 없다는 점에 유의하십시오.
[System.Xml.Serialization.XmlElementAttribute ( "strFieldName", 양식 = System.Xml.Schema.XmlSchemaForm.Unqualified)]
//또는
[XmlIgnore] string [] strFielsName {get; set;}
나는 동일한 문제가 있었고 제 경우에는 객체에 ReadOnlyCollection이있었습니다. 콜렉션은 직렬화 할 Add 메소드를 구현해야합니다.
IList
필요할 때List
. - Paul Aldred-Bann