318

C #.NET 2.0을 사용하면 복합 데이터 클래스가[Serializable]그것에 대한 속성. 나는XMLSerializer클래스를 생성자에 전달합니다.

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

나는 예외를 말하고있다 :

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

데이터 클래스에는 또 다른 복합 객체가 있습니다. 이것도 필요합니다[Serializable]애트리뷰트를 사용하거나 맨 위 오브젝트에 배치하여 내부의 모든 오브젝트에 재귀 적으로 적용합니까?

16 답변


394

당신이 얻는 내부 예외를 보라. 직렬화에 문제가있는 필드 / 속성을 알려줍니다.

xml serialization에서 필드 / 속성을 제외시킬 수 있습니다.[XmlIgnore]속성.

나는 그렇게 생각하지 않는다.XmlSerializer~을 사용하다[Serializable]속성, 그래서 그게 문제가 의심.


  • 내 물건에는 위 필드가있어서 예외가 발생했습니다. Uri 클래스에는 매개 변수없는 생성자가 없습니다. 팁 고마워. - ford
  • Google 검색을 통해이 문제가 발생했습니다. 내 특정 문제는 " 연재 됨 " class asIList필요할 때List. - Paul Aldred-Bann
  • " 내부 예외 "는 어떻게 보입니까? - David
  • & #예외 '를 추가하십시오. 시계에 - arolson101
  • 고마워,이 대답은 나를 도왔다. 처음에는 내부 예외를 살펴본 후 주 클래스를 언급하는 것을 보았습니다. 그러나 나는 innrexceptions의 innerexceptions로 드릴 다운 수있는 깨달았고, 결국, 5 레벨 아래로, 내가 문제를 발견. 나는 상충하는 수업을했다. 감사. - Louis van Tonder

108

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


  • 알림 주셔서 감사합니다! 나는 이것이 약간의 설명과 함께 런타임 오류라고 싫어. - Jared Updike
  • 나는이 실수를 반복해서 계속한다. 매개 변수가없는 생성자를 사용하도록 상기시켜 주셔서 감사합니다 ^^ - aZtraL-EnForceR

22

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

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

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

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

[XmlType("BaseNamespace.Class1")]

참고 : 클래스의 레이어가 더 많은 경우 속성을 추가해야합니다.


  • 이 문제가 해결되었습니다. +1 감사합니다. 나는 Config 내부 클래스가있는 여러 개의 Processor * 객체와 비슷한 설정을 사용했습니다. 런타임에서 SomeNS.Processor1.Config와 SomeNS.Processor2.Config를 구별하지 못했습니다. - damix911

7

또한 유의하십시오.XmlSerializer추상 속성을 serialize 할 수 없습니다. 내 질문보기이리(어느 솔루션 코드를 추가했는지) ..

XML 직렬화 및 상속 된 형식


6

나에 대한 가장 일반적인 이유 :

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


5

직렬화 그래프 내의 모든 오브젝트는 직렬화 가능해야한다.

이후XMLSerializer직렬화 과정을 더 자세히 디버깅하려면이 링크를 확인하십시오.

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

방법 : 생성 된 .NET XmlSerializer 어셈블리로 디버그


5

특정 속성 (예 : 사전 또는 모든 클래스)을 처리해야하는 경우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)]

나는 자동 생성 된 시퀀스에서 마지막 것보다 높은 순서로 비슷한 속성을 추가 할 필요가 있었고 이것으로 나를 고정시켰다.


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


2

방금 같은 오류가 발생하여 유형의 속성을 발견했습니다.IEnumerable<SomeClass>문제였다. 그것은 나타난다.IEnumerable직접 직렬화 할 수 없습니다.


1

주문이 연속적으로 두 요소에 대해 동일했던 상황이있었습니다.

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

.... 일부 코드 ...

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

클래스의 각 새 Property에 대해 순서를 하나씩 늘리도록 코드를 변경하면 오류가 사라집니다.


0

또한 사용자 인터페이스 컨트롤을 직렬화 할 수 없으며 클립 보드에 전달할 객체는 직렬화 가능해야하며 그렇지 않으면 다른 프로세스로 전달할 수 없다는 점에 유의하십시오.


0

나는NetDataSerialiser직렬화하는 클래스 내 도메인 클래스.NetDataContractSerializer 클래스.

도메인 클래스는 클라이언트와 서버간에 공유됩니다.


0

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

//또는

[XmlIgnore] string [] strFielsName {get; set;}


0

나는 동일한 문제가 있었고 제 경우에는 객체에 ReadOnlyCollection이있었습니다. 콜렉션은 직렬화 할 Add 메소드를 구현해야합니다.


  • 이것은 질문에 대한 적절한 대답이 아닙니다. 이미이 질문에 대한 15 가지 답변이 있습니다. 당신의 대답이 다른 사람들보다 낫다고 생각한다면 그것에 대한 자세한 내용을 제공해야합니다. 일부 코드 & 출력 스 니펫은 항상 사용자를 돕습니다. 답변을 게시하기 전에 >stackoverflow.com/help/how-to-answer - Amit Phaltankar

연결된 질문


관련된 질문

최근 질문