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


332

C # .NET 2.0을 사용하면 [Serializable]속성 이있는 복합 데이터 클래스가 있습니다 . XMLSerializer클래스를 만들고 생성자에 전달합니다.

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

예외가 발생했습니다.

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

데이터 클래스 내부에는 또 다른 복합 객체가 있습니다. 이것도 [Serializable]속성 을 가져야합니까 , 아니면 최상위 객체에 포함 시켜서 내부의 모든 객체에 재귀 적으로 적용합니까?

답변:


413

당신이 받고있는 내부 예외를보십시오. 직렬화에 문제가있는 필드 / 프로퍼티를 알려줍니다.

속성으로 장식하여 필드 / 속성을 XML 직렬화에서 제외 할 수 있습니다 [XmlIgnore].

XmlSerializer[Serializable]속성을 사용하지 않으므로 문제가 의심됩니다.


11
내 개체에 Uri 필드가있어이 예외가 발생했습니다. Uri 클래스에는 매개 변수가없는 생성자가 없습니다. 팁 고마워.
ford

10
구글 검색 으로이 문제를 겪었습니다. 제 특정 문제는 IList필요할 때 와 같이 "직렬화 될"클래스에 속성 이 있다는 것 List입니다.
Paul Aldred-Bann

7
"내부 예외"를 어떻게 봅니까?
David

7
또는 시계에 '@exception'추가
arolson101

19
감사합니다.이 답변이 도움이되었습니다. 나는 처음에 내부 예외를 보았고 메인 클래스에 대한 언급을 보았습니다. 그러나 나는 innrexceptions의 내부 예외를 드릴 다운 할 수 있다는 것을 깨달았고 결국 5 레벨을 낮추면서 문제를 발견했습니다. 갈등이있는 수업이있었습니다. 감사.
Louis van Tonder

111

직렬화 된 클래스에는 기본 (즉, 매개 변수가없는) 생성자가 있어야합니다. 생성자가 전혀 없다면 괜찮습니다. 그러나 매개 변수가있는 생성자가있는 경우 기본 구성 요소도 추가해야합니다.


4
알림 주셔서 감사합니다! 나는 이것이 약간의 설명으로 런타임 오류라는 것을 싫어합니다.
Jared Updike 2013

나는이 실수를 계속해서 반복하고있다. 매개 변수가없는 생성자 ^^ 사용하는 나에게 상기시켜 주셔서 감사합니다
aZtraL - 집행자

25

비슷한 문제가 있었는데 serializer가 동일한 이름을 가진 2 개의 클래스 (하나는 다른 클래스의 하위 클래스)를 구별 할 수 없다는 것이 밝혀졌습니다. 내부 예외는 다음과 같습니다.

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

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

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

[XmlType("BaseNamespace.Class1")]

참고 : 클래스 계층이 더 있으면 속성도 추가해야합니다.


이로 인해 문제가 해결되었습니다. +1; 여러 개의 Processor * 객체와 비슷한 설정을 가지고 있으며 각각은 구성 내부 클래스가 있습니다. 런타임에서 SomeNS.Processor1.Config와 SomeNS.Processor2.Config를 구별 할 수 없습니다.
damix911 2016 년


6

내가 가장 일반적인 이유 :

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


5

특정 속성 (예 : 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리플렉션을 사용하여 사용자 정의 클래스 를 구현하는 것이 간단 할 수 있습니다 .


4

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

나는 여기 에서 일을 발견했다 .


3

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

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

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


3

방금 같은 오류가 발생하여 유형의 속성이 IEnumerable<SomeClass>문제 라는 것을 알았습니다 . 이 나타납니다 IEnumerable직접 직렬화 할 수 없습니다.

대신에을 사용할 수 있습니다 List<SomeClass>.


2

나는 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가 공용 속성에 대한 리플렉션을 사용하고 있다고 생각합니다.


1

두 요소가 연속으로 주문이 같은 상황이 발생했습니다.

[System.Xml.Serialization.XmlElementAttribute(IsNullable = true, Order = 0, ElementName = "SeriousInjuryFlag")]

.... 일부 코드 ...

[System.Xml.Serialization.XmlElementAttribute(IsNullable = true, Order = 0, ElementName = "AccidentFlag")]

클래스의 새 속성마다 하나씩 순서를 늘리기 위해 코드를 변경하면 오류가 사라졌습니다.


1

데이터 유형이-인 속성을 만들 때 동일한 오류가 발생했습니다 Type. 이것에 오류가 발생했습니다. 유형을 반영하는 동안 오류가 발생했습니다. 디버그 도크에서 모든 예외의 'InnerException'을 계속 확인하고 Type제 경우 에는 특정 필드 이름 ()을 얻었습니다 . 해결책은 다음과 같습니다.

    [XmlIgnore]
    public Type Type { get; set; }

0

또한 사용자 인터페이스 컨트롤을 직렬화 할 수 없으며 클립 보드에 전달할 객체는 직렬화 할 수 있어야합니다. 그렇지 않으면 다른 프로세스로 전달할 수 없습니다.



0

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


이것은 질문에 대한 정답이 아닙니다. 이 질문에 이미 다른 15 가지 답변이 있습니다. 귀하의 답변이 다른 답변보다 낫다고 생각되면 이에 대한 자세한 정보를 제공해야합니다. 일부 코드 및 출력 스 니펫을 제공하면 항상 사용자에게 도움이됩니다. 답변을 게시하기 전에 고려 읽기 -> stackoverflow.com/help/how-to-answer
아 미트 Phaltankar

0

지금까지 설명한 모든 것에 대해 약간 다른 해결책이 있습니다. 따라서 미래의 문명을 위해 여기에 내 것이 있습니다!

원래 유형이 다음 TimeSpan과 같이 변경되어 "time"이라는 데이터 유형을 선언 했습니다 String.

[System.Xml.Serialization.XmlElementAttribute(DataType="time", Order=3)]

그러나 실제 유형은 문자열이었습니다

public string TimeProperty {
    get {
        return this.timePropertyField;
    }
    set {
        this.timePropertyField = value;
        this.RaisePropertyChanged("TimeProperty");
    }
}

DateType속성 을 제거하여 Xml직렬화 할 수 있습니다

[System.Xml.Serialization.XmlElementAttribute(Order=3)]
public string TimeProperty {
    get {
        return this.timePropertyField;
    }
    set {
        this.timePropertyField = value;
        this.RaisePropertyChanged("TimeProperty");
    }
}

0
[System.Xml.Serialization.XmlElementAttribute("strFieldName", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]

또는

[XmlIgnore]
string [] strFielsName {get;set;}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.