.Net을 사용하면 XmlSerializer를 사용할 때 어떤 제한 사항이 있습니까?

StackOverflow https://stackoverflow.com/questions/109318

  •  01-07-2019
  •  | 
  •  

문제

.Net을 사용하면 XmlSerializer를 사용할 때 어떤 제한 사항이 있습니까?예를 들어 이미지를 XML로 직렬화할 수 있나요?

도움이 되었습니까?

해결책

XmlSerializer에는 몇 가지 단점이 있습니다.

  1. 직렬화되는 모든 유형을 알아야 합니다.직렬 변환기가 알지 못하는 유형을 나타내는 인터페이스를 통해 무언가를 전달할 수 없습니다.
  2. 순환 참조를 수행할 수 없습니다.
  3. 개체 그래프에서 여러 번 참조되면 동일한 개체를 여러 번 직렬화합니다.
  4. 비공개 필드 직렬화를 처리할 수 없습니다.

나는 (멍청하게도) 이러한 문제 중 일부를 해결하기 위해 자체 직렬 변환기를 작성했습니다.그러지 마세요.그것은 많은 작업이며 몇 달이 지나면 미묘한 버그를 발견하게 될 것입니다.내가 직접 직렬 변환기와 포맷터를 작성하면서 얻은 유일한 것은 개체 그래프 직렬화와 관련된 세부 사항을 더 잘 이해했다는 것입니다.

나는 찾았다 NetDataContractSerializer WCF가 나왔을 때.XmlSerializer가 수행하지 않는 위의 모든 작업을 수행합니다.XmlSerializer와 유사한 방식으로 직렬화를 구동합니다.직렬화할 항목을 직렬 변환기에 알리기 위해 다양한 속성이나 필드를 속성으로 장식합니다.NetDataContractSerializer로 작성한 사용자 정의 직렬 변환기를 교체했으며 결과에 매우 만족했습니다.나는 그것을 강력히 추천합니다.

다른 팁

나는 일반적으로 XmlSerializer가 단순한 DTO 이상의 POCO에 대해서는 좋지 않은 선택이라고 생각합니다.특정 XML이 필요한 경우 Xml*Attribute 및/또는 IXmlSerialized 경로를 사용할 수 있지만 개체가 꽤 엉망이 된 상태로 남습니다.

어떤 목적에서는 한계가 있음에도 불구하고 여전히 분명한 선택입니다.그러나 단순히 데이터를 저장하고 다시 로드하는 경우에는 BinaryFormatter가 위험이 적고 훨씬 더 쉬운 선택이라는 것을 알았습니다.

다음은 XmlSerializer의 몇 가지 성가심 목록입니다. 대부분은 한 지점 또는 다른 지점에서 물렸으며 다른 지점에서는 발견했습니다. MSDN:

  • 인수가 없는 공개 생성자가 필요합니다.
  • 공개 읽기/쓰기 속성 및 필드만 직렬화합니다.
  • 모든 유형을 알아야 함
  • 실제로 get_* 및 set_*를 호출하므로 유효성 검사 등이 수행됩니다.실행됩니다.이것은 좋을 수도 있고 나쁠 수도 있습니다(통화 순서도 생각해 보세요).
  • 특정 규칙을 준수하는 IEnumerable 또는 ICollection 컬렉션만 직렬화합니다.

XmlSerializer는 IEnumerable 또는 ICollection을 구현하는 클래스에 특별한 처리를 제공합니다.IEnumerable을 구현하는 클래스는 단일 매개 변수를 사용하는 공용 Add 메서드를 구현해야 합니다.Add 메서드의 매개 변수는 GetEnumerator에서 반환된 값에 대한 Current 속성에서 반환된 것과 동일한 유형이거나 해당 유형의 기본 중 하나여야 합니다.

IEnumerable 외에 ICollection(예: CollectionBase)을 구현하는 클래스에는 정수를 사용하는 공용 항목 인덱싱된 속성(C#의 인덱서)과 정수 유형의 공용 Count 속성이 있어야 합니다.Add 메서드에 대한 매개 변수는 Item 속성에서 반환된 것과 동일한 유형이거나 해당 유형의 기본 중 하나여야 합니다.ICollection을 구현하는 클래스의 경우 직렬화할 값은 GetEnumerator를 호출하는 것이 아니라 인덱싱된 Item 속성에서 검색됩니다.

  • IDictionary를 직렬화하지 않습니다.
  • 앱 도메인에서 언로드되지 않을 수 있는 동적으로 생성된 어셈블리를 사용합니다.

성능을 높이기 위해 XML 직렬화 인프라는 지정된 형식을 직렬화 및 역직렬화하는 어셈블리를 동적으로 생성합니다.인프라는 해당 어셈블리를 찾아 재사용합니다.이 동작은 다음 생성자를 사용할 때만 발생합니다.

xmlserializer.xmlserializer (유형) xmlserializer.xmlserializer (type, string)

다른 생성자를 사용하는 경우 동일한 어셈블리의 여러 버전이 생성되고 언로드되지 않으므로 메모리 누수가 발생하고 성능이 저하됩니다.

  • ArrayList[] 또는 List<T>[]를 직렬화할 수 없습니다.
  • 다른 이상한 극단적인 경우가 있음

다음 조건이 true인 경우 XmlSerializer를 인스턴스화하여 열거형을 직렬화할 수 없습니다.열거형은 unsigned long(C#의 경우 ulong) 유형이고 열거형에는 9,223,372,036,854,775,807보다 큰 값을 가진 멤버가 포함되어 있습니다.

XmlSerializer 클래스는 더 이상 [사용되지 않음]으로 표시된 개체를 직렬화하지 않습니다.

개체를 역직렬화하려면 임시 디렉터리(TEMP 환경 변수로 정의됨)에 쓸 수 있는 권한이 있어야 합니다.

  • 오류에 대한 유용한 정보를 얻으려면 .InnerException을 읽어야 합니다.

또 다른 문제는 XmlSerializer의 생성자를 호출하면 런타임에 코드가 컴파일되고 역직렬화를 수행하는 코드가 포함된 임시 DLL(%temp% 폴더에 있음)이 생성된다는 것입니다.

app.config에 다음 줄을 추가하면 코드를 볼 수 있습니다.

  <system.diagnostics>
    <switches>
      <add name="XmlSerialization.Compilation" value="4"/>
    </switches>
  </system.diagnostics>

클래스를 처음 직렬화하는 경우 시간이 많이 걸리며 컴파일하고 디스크에 쓸 수 있는 권한이 있는 코드가 필요합니다.

이 문제를 해결하는 방법은 VS 2005+와 함께 제공되는 sGen.exe 도구를 사용하여 이러한 DLL을 사전 컴파일하는 것입니다.

자세한 내용은 여기를 참조하세요..

제한이 있는지는 잘 모르겠습니다..하지만 .NET 1.1의 XmlSerialization에는 메모리 누수 버그가 있었습니다. 이 문제를 해결하려면 캐시 직렬 변환기 개체를 만들어야 했습니다.실제로 이 문제가 .net 2.0 이상에서 해결되었는지 확실하지 않습니다...

이론적으로 작성하는 모든 클래스는 XmlSerializer를 통해 제공될 수 있습니다.그러나 공개 필드에만 액세스할 수 있으며 클래스는 올바른 속성으로 표시되어야 합니다(예:Xml속성).기본 프레임워크에서도 모든 것이 XmlSerializer를 지원하는 것은 아닙니다.예를 들어 System.Collections.Generic.Dictionary<>입니다.

제가 생각할 수 있는 한 가지 제한 사항은 XmlSerialization이 옵트아웃된다는 것입니다.즉, 직렬화를 원하지 않는 클래스의 모든 속성은 [XmlIgnore]로 장식되어야 합니다.모든 속성이 선택되어 있는 DataContractSerializer와는 대조적으로 포함 특성을 명시적으로 선언해야 합니다.여기에 좋은 것이 있습니다 글쓰기.

이미지 또는 해당 이진 배열은 XmlSerializer에 의해 base64로 인코딩된 텍스트로 직렬화됩니다.

예를 들어 IDictionary 인터페이스를 구현하는 클래스를 직렬화할 수 없습니다.

컬렉션의 경우 단일 인수를 사용하는 Add 메서드가 있어야 합니다.특별히 XML이 아닌 텍스트 형식만 필요한 경우 JSON을 사용해 볼 수 있습니다.저는 .NET용으로 하나를 개발했습니다. JsonEx 직렬 변환기, 그리고 에서 다른 제품도 사용할 수 있습니다. http://www.json.org.

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