문제

C# .NET 2.0을 사용하여 다음을 포함하는 복합 데이터 클래스가 있습니다. [Serializable] 그것에 속성.나는 XMLSerializer 클래스를 생성하고 이를 생성자에 전달합니다.

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

다음과 같은 예외가 발생합니다.

유형을 반영하는 중에 오류가 발생했습니다.

데이터 클래스 내부에는 또 다른 복합 개체가 있습니다.이것도 필요합니까? [Serializable] 속성을 사용하거나 최상위 객체에 배치하여 내부의 모든 객체에 재귀적으로 적용합니까?

도움이 되었습니까?

해결책

발생하는 내부 예외를 살펴보십시오.직렬화에 문제가 있는 필드/속성을 알려줍니다.

필드/속성을 다음과 같이 장식하여 XML 직렬화에서 제외할 수 있습니다. [XmlIgnore] 기인하다.

나는 그렇게 생각하지 않는다 XmlSerializer 을 사용합니다 [Serializable] 속성이므로 이것이 문제인지 의심됩니다.

다른 팁

직렬화된 클래스에는 기본값(예:매개변수 없는) 생성자.생성자가 전혀 없어도 괜찮습니다.하지만 매개변수가 있는 생성자가 있는 경우 기본 생성자도 추가해야 합니다.

비슷한 문제가 있었는데, 직렬 변환기가 같은 이름을 가진 두 클래스(하나는 다른 클래스의 하위 클래스)를 구별할 수 없다는 것이 밝혀졌습니다.내부 예외는 다음과 같습니다.

'Types BaseNamespace.Class1' 및 'BaseNamespace.SubNamespace.Class1'은 모두 '' 네임스페이스의 XML 유형 이름 'Class1'을 사용합니다.XML 특성을 사용하여 유형에 대한 고유한 XML 이름 및/또는 네임스페이스를 지정합니다.

여기서 BaseNamespace.SubNamespace.Class1은 BaseNamespace.Class1의 하위 클래스입니다.

내가 해야 할 일은 클래스 중 하나에 속성을 추가하는 것이었습니다(기본 클래스에 추가했습니다).

[XmlType("BaseNamespace.Class1")]

메모:더 많은 클래스 레이어가 있는 경우 해당 클래스에도 속성을 추가해야 합니다.

또한 XmlSerializer 추상 속성을 직렬화할 수 없습니다.내 질문 보기 여기 (솔루션 코드를 추가했습니다) ..

XML 직렬화 및 상속된 유형

제가 생각하는 가장 일반적인 이유는 다음과 같습니다.

 - the object being serialized has no parameterless constructor
 - the object contains Dictionary
 - the object has some public Interface members

직렬화 그래프의 모든 객체는 직렬화 가능해야 합니다.

부터 XMLSerializer 블랙박스입니다. 직렬화 프로세스를 더 자세히 디버깅하려면 이 링크를 확인하세요.

XmlSerializer가 임시 어셈블리를 출력하는 위치 변경

어떻게:.NET XmlSerializer 생성 어셈블리로 디버그

특정 속성을 처리해야 하는 경우(예:사전 또는 모든 클래스)를 구현할 수 있습니다. IXml직렬 가능 더 많은 자유를 선사하는 인터페이스 더 장황한 코딩 비용으로.

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를 "확장"하는 정교한 방법을 구현하는 우아한 방법을 보여줍니다.


기사는 다음과 같이 말합니다.

IXmlSerialized는 공식 문서에서 다루지만 문서에는 공개적으로 사용하기 위한 것이 아니라고 명시되어 있으며 그 이상의 정보는 제공하지 않습니다.이는 개발 팀이 이 확장성 후크를 수정, 비활성화하거나 심지어 완전히 제거할 수 있는 권한을 보유하기를 원했음을 나타냅니다.그러나 이러한 불확실성을 기꺼이 받아들이고 미래에 발생할 수 있는 변화에 대처하려는 한, 이를 활용하지 못할 이유는 전혀 없습니다.

그렇기 때문에 나는 당신 자신의 것을 구현하는 것을 제안합니다 IXmlSerializable 너무 복잡한 구현을 피하기 위해 클래스를 사용합니다.

...우리의 사용자 정의를 구현하는 것은 간단할 수 있습니다. XmlSerializer 리플렉션을 활용한 수업

.Net 2.0의 Dictionary 클래스는 XML을 사용하여 직렬화할 수 없지만 이진 직렬화를 사용하면 잘 직렬화된다는 사실을 발견했습니다.

해결 방법을 찾았습니다. 여기.

최근에 새 속성을 추가할 때 웹 참조 부분 클래스에서 이것을 얻었습니다.자동 생성 클래스에 다음 속성이 추가되었습니다.

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

자동 생성된 시퀀스에서 마지막 것보다 순서가 하나 더 높은 유사한 속성을 추가해야 했고 이로 인해 문제가 해결되었습니다.

나 역시 직렬화 가능 속성이 객체에 있어야 한다고 생각했지만, 내가 완전히 멍청한 놈이 아닌 한(심야 코딩 세션 중) 다음은 다음 작업에서 작동합니다. 스니펫컴파일러:

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", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]

//또는

xmlignore] string [] strfielsname {get; set;}

나도 같은 문제가 있었고 내 경우에는 개체에 ReadOnlyCollection이 있었습니다.컬렉션이 직렬화 가능하려면 Add 메서드를 구현해야 합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top