XmlSerializer-유형을 반영하는 중에 오류가 발생했습니다
C # .NET 2.0을 사용하면 [Serializable]
속성 이있는 복합 데이터 클래스가 있습니다 . XMLSerializer
클래스를 만들고 생성자에 전달합니다.
XmlSerializer serializer = new XmlSerializer(typeof(DataClass));
예외가 발생했습니다.
유형을 반영하는 중에 오류가 발생했습니다.
데이터 클래스 내부에는 또 다른 복합 객체가 있습니다. 이것도 [Serializable]
속성 을 가져야합니까 , 아니면 최상위 객체에 포함 시켜서 내부의 모든 객체에 재귀 적으로 적용합니까?
당신이 받고있는 내부 예외를보십시오. 직렬화에 문제가있는 필드 / 프로퍼티를 알려줍니다.
속성으로 장식하여 필드 / 속성을 XML 직렬화에서 제외 할 수 있습니다 [XmlIgnore]
.
나는 그것이 속성 을 XmlSerializer
사용 한다고 생각하지 않으므로 그것이 [Serializable]
문제인지 의심합니다.
직렬화 된 클래스에는 기본 (즉 매개 변수가없는) 생성자가 있어야합니다. 생성자가 전혀 없다면 괜찮습니다. 그러나 매개 변수가있는 생성자가있는 경우 기본 구성 요소도 추가해야합니다.
비슷한 문제가 있었는데 serializer가 동일한 이름을 가진 2 개의 클래스 (하나는 다른 클래스의 하위 클래스)를 구별 할 수 없다는 것이 밝혀졌습니다. 내부 예외는 다음과 같습니다.
'Types BaseNamespace.Class1'및 'BaseNamespace.SubNamespace.Class1'은 모두 네임 스페이스 ''의 XML 유형 이름 'Class1'을 사용합니다. XML 속성을 사용하여 유형에 고유 한 XML 이름 및 / 또는 네임 스페이스를 지정하십시오.
여기서 BaseNamespace.SubNamespace.Class1은 BaseNamespace.Class1의 서브 클래스입니다.
내가해야 할 일은 클래스 중 하나에 속성을 추가하는 것이 었습니다 (기본 클래스에 추가했습니다).
[XmlType("BaseNamespace.Class1")]
참고 : 클래스 계층이 더 있으면 속성도 추가해야합니다.
또한 XmlSerializer
추상 속성을 직렬화 할 수 없다는 점에 유의 하십시오. 여기에서 내 질문을 참조 하십시오 (솔루션 코드를 추가했습니다).
내가 가장 일반적인 이유 :
- the object being serialized has no parameterless constructor
- the object contains Dictionary
- the object has some public Interface members
직렬화 그래프의 모든 개체는 직렬화 가능해야합니다.
XMLSerializer
블랙 박스 이므로 직렬화 프로세스로 추가로 디버그하려면이 링크를 확인하십시오.
XmlSerializer가 임시 어셈블리를 출력하는 위치 변경
방법 : .NET XmlSerializer 생성 어셈블리로 디버그
특정 속성 (예 : Dictionary 또는 클래스)을 처리해야하는 경우 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
직접 직렬화 할 수 없습니다.
대신에을 사용할 수 있습니다 List<SomeClass>
.
두 요소가 연속으로 주문이 같은 상황이 발생했습니다.
[System.Xml.Serialization.XmlElementAttribute(IsNullable = true, Order = 0, ElementName = "SeriousInjuryFlag")]
.... 일부 코드 ...
[System.Xml.Serialization.XmlElementAttribute(IsNullable = true, Order = 0, ElementName = "AccidentFlag")]
클래스의 새 속성마다 하나씩 순서를 늘리기 위해 코드를 변경하면 오류가 사라졌습니다.
또한 사용자 인터페이스 컨트롤을 직렬화 할 수 없으며 클립 보드에 전달할 객체는 직렬화 가능해야하며 그렇지 않으면 다른 프로세스로 전달할 수 없습니다.
NetDataSerialiser
클래스를 사용하여 도메인 클래스를 직렬화했습니다. NetDataContractSerializer 클래스 .
도메인 클래스는 클라이언트와 서버간에 공유됩니다.
[System.Xml.Serialization.XmlElementAttribute ( "strFieldName", 양식 = System.Xml.Schema.XmlSchemaForm.Unqualified)]
//또는
[XmlIgnore] 문자열 [] strFielsName {get; set;}
나는 같은 문제가 있었고 내 경우에는 객체에 ReadOnlyCollection이있었습니다. 컬렉션은 직렬화 가능하도록 Add 메소드를 구현해야합니다.
참고 URL : https://stackoverflow.com/questions/60573/xmlserializer-there-was-an-error-reflecting-type
'Programming' 카테고리의 다른 글
git에서 merge --squash와 rebase의 차이점은 무엇입니까? (0) | 2020.03.06 |
---|---|
런타임에 메소드가 정의 된 위치를 찾는 방법은 무엇입니까? (0) | 2020.03.06 |
Task.Delay 사용시기, Thread.Sleep 사용시기 (0) | 2020.03.06 |
가시성을 설정하는 jQuery .hide ()와 동일 : hidden (0) | 2020.03.06 |
CSS3 calc로 덜 공격적인 컴파일 (0) | 2020.03.06 |