- .Net/C# 응용 프로그램에서 나는 서로에 대한 참조가있는 데이터 구조를 가지고 있습니다.
- 내가 serialize 할 때 .Net은 별도의 개체 복사본으로 모든 참조를 serialize합니다.
- 다음 예제에서는 'Person'의 배열로 serialize하려고 시도하고 있습니다.
'Person'은 다른 사람을 참조 할 수 있습니다. 동일한 개체에 대한 두 개의 참조가 있기 때문에 위의 코드에서 .net XML 직렬화 - 객체 복사본 대신 참조 저장
public class Person { public string Name; public Person Friend; } Person p1 = new Person(); p1.Name = "John"; Person p2 = new Person(); p2.Name = "Mike"; p1.Friend = p2; Person[] group = new Person[] { p1, p2 }; XmlSerializer ser = new XmlSerializer(typeof(Person[])); using (TextWriter tw = new StreamWriter("test.xml")) ser.Serialize(tw,group); //above code generates following xml <ArrayOfPerson> <Person> <Name>John</Name> <Friend> <Name>Mike</Name> </Friend> </Person> <Person> <Name>Mike</Name> </Person> </ArrayOfPerson>
같은 '마이크'객체는 두 위치에있다.
- 직렬화를 해제하는 동안 두 개의 서로 다른 개체가되어 직렬화 될 때 정확한 상태가 아닙니다.
- 나는 이것을 피하고 serialize 된 xml에있는 객체의 사본 만 갖고 싶습니다. 모든 참조는이 사본을 참조해야합니다. deserialization 후, 나는 같은 오래된 데이터 구조로 돌아가고 싶다.
- 가능합니까?
29
A
답변
33
XmlSerializer으로는 불가능합니다. PreserveObjectReferences 속성을 사용하면 DataContractSerializer으로이 작업을 수행 할 수 있습니다. 세부 사항을 설명하는 post을 살펴보십시오.
public class Person
{
public string Name;
public Person Friend;
}
class Program
{
static void Main(string[] args)
{
Person p1 = new Person();
p1.Name = "John";
Person p2 = new Person();
p2.Name = "Mike";
p1.Friend = p2;
Person[] group = new Person[] { p1, p2 };
var serializer = new DataContractSerializer(group.GetType(), null,
0x7FFF /*maxItemsInObjectGraph*/,
false /*ignoreExtensionDataObject*/,
true /*preserveObjectReferences : this is where the magic happens */,
null /*dataContractSurrogate*/);
serializer.WriteObject(Console.OpenStandardOutput(), group);
}
}
이 다음과 같은 XML이 생성 : 이제 생성자에서 false
에 PreserveObjectReferences
을 설정
<ArrayOfPerson z:Id="1" z:Size="2" xmlns="http://schemas.datacontract.org/2004/07/ToDelete" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
<Person z:Id="2">
<Friend z:Id="3">
<Friend i:nil="true"/>
<Name z:Id="4">Mike</Name>
</Friend>
<Name z:Id="5">John</Name>
</Person>
<Person z:Ref="3" i:nil="true"/>
</ArrayOfPerson>
을하고 당신이 얻을 것이다 :
<ArrayOfPerson xmlns="http://schemas.datacontract.org/2004/07/ToDelete" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Person>
<Friend>
<Friend i:nil="true"/>
<Name>Mike</Name>
</Friend>
<Name>John</Name>
</Person>
<Person>
<Friend i:nil="true"/>
<Name>Mike</Name>
</Person>
</ArrayOfPerson>
여기
은 샘플 코드입니다 이 방법으로 생성 된 XML은 상호 운용 할 수 없다는 점을 언급 할 필요가 있습니다. DataContractSerializer로만 역 직렬화 할 수 있습니다 ( BinaryFormatter과 동일한 설명).
4
ExtendedXmlSerializer를 사용할 수 있습니다.
이public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public Person Boss { get; set; }
}
public class Company
{
public List<Person> Employees { get; set; }
}
다음과 같이 순환 참조로 객체를 생성 : 당신은 참조 객체로 Person 클래스를 구성해야합니다
var boss = new Person {Id = 1, Name = "John"};
boss.Boss = boss; //himself boss
var worker = new Person {Id = 2, Name = "Oliver"};
worker.Boss = boss;
var obj = new Company
{
Employees = new List<Person>
{
worker,
boss
}
};
당신은 클래스가있는 경우 여기에 직렬화 object reference and circular reference
의 예입니다 :
var serializer = new ConfigurationContainer().ConfigureType<Person>()
.EnableReferences(p => p.Id)
.Create();
마지막으로 obj를 직렬화 할 수 있습니다. 요법 :
var xml = serializer.Serialize(obj);
출력 XML은 다음과 같이 표시됩니다
<?xml version="1.0" encoding="utf-8"?>
<Company xmlns="clr-namespace:ExtendedXmlSerializer.Samples.ObjectReference;assembly=ExtendedXmlSerializer.Samples">
<Employees>
<Capacity>4</Capacity>
<Person Id="2">
<Name>Oliver</Name>
<Boss Id="1">
<Name>John</Name>
<Boss xmlns:exs="https://extendedxmlserializer.github.io/v2" exs:entity="1" />
</Boss>
</Person>
<Person xmlns:exs="https://extendedxmlserializer.github.io/v2" exs:entity="1" />
</Employees>
</Company>
ExtendedXmlSerializer 지원 .NET 4.5 및 .NET 코어.
+0
당신은 자신의 소프트웨어를 홍보하고 있다고 언급해야합니다. 그것은 좋은 일을하는 것처럼 보이지만 .net 프레임 워크의 일부가 아닙니다. – MikeT
관련 문제
- 1. XML 객체 역 직렬화
- 2. XML XNA 객체 역 직렬화
- 3. XML에 객체 직렬화 및 XML
- 4. XML 직렬화 또는 XML 객체 읽기?
- 5. .net 소켓을 통해 XML 직렬화 된 객체 보내기
- 6. Rails 호환 .NET XML 직렬화
- 7. ArrayOfXxxx 대신 Xxxxs로 객체 배열 직렬화
- 8. 참조 및 기본 생성자가없는 객체 역 직렬화 (부스트 :: 직렬화)
- 9. DateTime XML 직렬화 역 직렬화
- 10. 참조 PHP 배열의 전체 복사본
- 11. 객체 직렬화
- 12. VSTO 통합 문서의 VSTO가 아닌 복사본 저장
- 13. NSXMLDocument 객체 직렬화
- 14. Java : 바이너리 대신 XML에서 직렬화/역 직렬화
- 15. .NET Xml 직렬화 : 정수가있는 정수 요소?
- 16. .NET 부모/자식 XML 비 직렬화 도움말
- 17. 전쟁 배포에서 객체 직렬화
- 18. ASP .NET - GridView에서 업데이트하기 전에 기존 데이터의 복사본 저장
- 19. 부스트 직렬화 다중 객체
- 20. .NET XmlSerializer를 여러 참조
- 21. XML 직렬화 - XML 루트
- 22. Java의 수동 객체 직렬화
- 23. XML 직렬화 및 비누 직렬화
- 24. Xml 직렬화/직렬화 해제 문제
- 25. C++에서의 XML 직렬화/직렬화
- 26. 객체 참조
- 27. XML 직렬화 (C# 3.0)
- 28. FlexJson 객체 참조를 역 직렬화
- 29. 이상한 .Net 직렬화 문제
- 30. ActiveRecord 직렬화 가능 속성의 XML 직렬화 문제
BinaryFormatter 및 SoapFormatter가 참조 값을 유지한다는 것을 알게되었습니다. – Palani
SoapFormatter는 더 이상 사용되지 않으며 제네릭을 지원하지 않습니다. –