- Trong .Net/C# Ứng dụng, tôi có cấu trúc dữ liệu có tham chiếu với nhau.
- Khi tôi tuần tự hóa chúng, .Net Nối tiếp tất cả các tham chiếu với các bản sao đối tượng riêng biệt.
- Trong ví dụ sau, tôi đang cố gắng tuần tự hóa thành mảng 'Person'
Một 'Người' có thể có tham chiếu đến một người khác.Nối tiếp XML trên mạng - Lưu trữ tham chiếu thay vì Sao chép đối tượng
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>
Trong đoạn mã trên, các 'Mike' cùng một đối tượng đang có trên hai nơi, vì có hai tài liệu tham khảo cho cùng một đối tượng.
- Trong khi deserializing, chúng trở thành hai đối tượng khác nhau, không phải là trạng thái chính xác khi chúng được tuần tự hóa.
- Tôi muốn tránh điều này và chỉ có bản sao của đối tượng trong xml được tuần tự hóa và tất cả các tham chiếu nên tham chiếu đến bản sao này. Sau khi deserialization, tôi muốn lấy lại, cùng một cấu trúc dữ liệu cũ.
- Có thể không?
Trả lời
Không thể với XmlSerializer. Bạn có thể đạt được điều này với DataContractSerializer bằng cách sử dụng thuộc tính PreserveObjectReferences. Bạn có thể xem qua số post để giải thích chi tiết.
Dưới đây là một số mẫu mã:
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);
}
}
này tạo ra XML sau:
<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>
Bây giờ thiết lập PreserveObjectReferences
-false
trong constructor và bạn sẽ có được điều này:
<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>
Điều đáng nói đến là XML được tạo ra theo cách này không tương thích được và chỉ có thể được deserialized với một DataContractSerializer (cùng một nhận xét như với BinaryFormatter).
Bạn có thể sử dụng ExtendedXmlSerializer. Dưới đây là một ví dụ về serialization object reference and circular reference
Nếu bạn có một lớp:
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; }
}
sau đó bạn tạo đối tượng với tham chiếu vòng tròn, như thế này:
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
}
};
Bạn phải cấu hình lớp người như đối tượng tham khảo :
var serializer = new ConfigurationContainer().ConfigureType<Person>()
.EnableReferences(p => p.Id)
.Create();
Cuối cùng, bạn có thể tuần tự hóa obj của mình vv:
var xml = serializer.Serialize(obj);
Output xml sẽ giống như thế này:
<?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 hỗ trợ .net 4.5 và Net Core.
bạn nên đề cập rằng bạn đang quảng cáo phần mềm của riêng mình, đó không phải là một phần của khung .net mặc dù trông giống như một chút công việc – MikeT
- 1. System.arrayCopy() sao chép đối tượng hoặc tham chiếu đến đối tượng?
- 2. Nối tiếp XML chậm
- 3. Nối tiếp một đối tượng thành JSON, XML, YAML?
- 4. lưu trữ xml bên trong đối tượng json
- 5. java null sao chép tham chiếu
- 6. Lưu trữ tham chiếu đến tham chiếu bằng Python?
- 7. Loại dữ liệu đối tượng nối tiếp Arduino, để tạo biến chứa tham chiếu đến cổng
- 8. Trình nối tiếp JSON tạo một đối tượng trống trên quá trình deserialization không thành công thay vì null
- 9. Lưu trữ đối tượng trên DB và lấy nó
- 10. Nối tiếp một đối tượng Có thể kéo trên Android
- 11. Làm cách nào để lưu trữ tham chiếu đến thuộc tính đối tượng trong đối tượng khác?
- 12. Nối tiếp gói Android cho mạng và/hoặc lưu trữ liên tục?
- 13. in_array trên các đối tượng có tham chiếu vòng tròn
- 14. Python có sao chép giá trị hoặc tham chiếu khi khởi tạo đối tượng không?
- 15. Javascript: Tham chiếu văn bản đối tượng trong chức năng của khóa riêng thay vì 'this'
- 16. STL: Lưu trữ các tham chiếu hoặc giá trị?
- 17. một hàm thay vì chương trình sao chép và dán
- 18. Làm cách nào để nối tiếp các đối tượng Ember?
- 19. java.util.Date sao chép hoặc sao chép để không hiển thị tham chiếu nội bộ
- 20. Sao chép tập tin qua kết nối mạng gián đoạn
- 21. Kết nối máy chủ lưu trữ nối tiếp USB USB?
- 22. AS3 - Sao chép một đối tượng
- 23. Khi nào nên bao gồm/sao chép mã của bên thứ ba, thay vì tham chiếu/liên kết mã đó?
- 24. đối tượng lưu trữ node.js trong redis
- 25. Lưu trữ Danh sách các đối tượng
- 26. Có thể sao chép tham chiếu đến đối tượng từ điển nhanh hơn hoặc truy cập trực tiếp từ điển từ điển không?
- 27. Dữ liệu lưu trữ blob tham chiếu trong SQL azure
- 28. đối tượng javascript pass như tham chiếu
- 29. Nối tiếp XML trong C#
- 30. Nối tiếp đối tượng và Deserialization?
Chỉ thấy BinaryFormatter và SoapFormatter giữ nguyên giá trị tham chiếu. – Palani
SoapFormatter đã không được chấp nhận và nó không hỗ trợ Generics. –