2008-09-20 21 views
30

Tôi muốn tuần tự hóa và deserialize đối tượng mà không cần phải lo lắng về toàn bộ đồ thị lớp.Serialization linh hoạt nhất cho các đối tượng .NET, nhưng đơn giản để thực hiện là gì?

Tính linh hoạt là chìa khóa. Tôi muốn để có thể serialize bất kỳ đối tượng thông qua cho tôi mà không cần các thuộc tính hoàn toàn cần thiết trong suốt toàn bộ đồ thị đối tượng.

Điều đó có nghĩa là Phân loại nhị phân không phải là tùy chọn vì nó chỉ hoạt động với các nền tảng .NET khác. Tôi sẽ cũng giống như nội dung có thể đọc được bởi một người và do đó có thể giải mã bằng chương trình quản lý và các thông dịch viên khác.

Tôi đã tìm thấy sự cố khi sử dụng DataContract, JSON và XML Serializers.

  • Hầu hết các lỗi này dường như tập trung xung quanh việc sắp xếp danh sách/từ điển (ví dụ: XML Serializable Generic Dictionary).
  • "Bổ sung các loại không biết tĩnh vào danh sách các loại nổi tiếng - cho dụ, bằng cách sử dụng thuộc tính KnownTypeAttribute hoặc bằng thêm chúng vào danh sách nổi tiếng loại truyền cho DataContractSerializer."

Vui lòng trả lời câu hỏi của bạn về trải nghiệm thực tế chứ không phải lý thuyết hoặc đọc bài viết.

Trả lời

53

bạn đã xem xét serializing để JSON thay vì XML?

Json.NET có bộ nối tiếp thực sự mạnh mẽ và linh hoạt không có vấn đề với từ điển Hashtables/generic và không yêu cầu bất kỳ thuộc tính cụ thể nào. Tôi biết vì tôi đã viết nó :)

Nó cung cấp cho bạn nhiều quyền kiểm soát thông qua các tùy chọn khác nhau trên bộ nối tiếp và nó cho phép bạn ghi đè cách một loại được tuần tự hóa bằng cách tạo JsonConverter cho nó.

Theo quan điểm của tôi, JSON dễ đọc hơn XML và Json.NET cung cấp tùy chọn viết JSON được định dạng độc đáo.

Cuối cùng, dự án là nguồn mở để bạn có thể bước vào mã và thực hiện các sửa đổi nếu cần.

+0

Tôi đã thử điều này, và nó đã cho tôi kết quả lỗi tốt hơn so với ra khỏi hộp DataManinpulator JSON Serializer, tuy nhiên nó vẫn bị đánh bom vì tham chiếu vòng lặp. Bất kỳ mẹo nào? Tôi đang xây dựng một khung thư và không có nhiều quyền kiểm soát cấu trúc thực tế của bất kỳ đối tượng nào. – mrbradleyt

+1

Đặt thuộc tính ReferenceLoopHandling trên JsonSerializer để bỏ qua. –

+6

Tôi sử dụng JSON.Net - nó hoàn toàn đá !!!!! –

0

Điều đơn giản nhất cần làm là đánh dấu đối tượng của bạn bằng thuộc tính Serializable và sau đó sử dụng trình định dạng nhị phân để xử lý tuần tự hóa. Toàn bộ biểu đồ lớp không phải là một vấn đề với điều kiện là bất kỳ đối tượng chứa nào cũng được đánh dấu là Serializable.

+0

Không chắc chắn nếu mrbradleyt muốn bỏ qua một số phần của biểu đồ lớp khi ông nói rằng ông không muốn lo lắng về nó. Trong trường hợp đó, không phải tất cả các thuộc tính cần được Serializable (NonSerializedAttribute có thể đánh dấu các lĩnh vực cần được loại trừ) –

+0

Có, điểm lấy. Ông cũng chỉ làm rõ rằng ông cần một định dạng không nhị phân, vì vậy giải pháp của tôi sẽ không làm việc cho anh ta. –

+0

Người hỏi đã loại trừ đặc biệt việc tuần tự hóa nhị phân. –

1

Trình xử lý trung gian trong khung công tác XNA khá thú vị. Bạn có thể tìm thấy một loạt các hướng dẫn về sử dụng nó tại http://blogs.msdn.com/shawnhar

+0

Cụ thể hơn, bạn có thể tìm thấy tất cả các bài viết của Shawn liên quan đến bộ nối tiếp trung gian ở đây: http://www.talula.demon.co.uk/blogindex.html#intermediateserializer –

1

SOAP serialization làm việc tốt cho tôi, thậm chí cho các đối tượng không được đánh dấu với [Serializable]

+0

Bạn sử dụng lớp nào? – mrbradleyt

+0

Tôi tin rằng việc sử dụng serialization SOAP không được khuyến khích từ NET 2.0. Trên thực tế nó thậm chí không xử lý Generics. http://social.msdn.microsoft.com/Forums/en-US/netfxremoting/thread/ee4a7a63-290e-432f-bd45-44f4cb7a3467/ –

+0

Một nơi nào đó trong Serialization.Formatters.Soap – ripper234

2

Từ yêu cầu của bạn có vẻ như Xml serialization là tốt nhất.

Bạn gặp phải vấn đề gì với bộ sưu tập khi tuần tự hóa? Nếu bạn đang đề cập đến việc không biết những thuộc tính nào để sử dụng trên Danh sách hoặc tương tự, bạn có thể thử thuộc tính XmlArray trên thuộc tính của bạn. Bạn chắc chắn có thể sắp xếp một bộ sưu tập.

+0

Bạn có thể vui lòng xây dựng trên XmlArray không thuộc tính ... tôi đã gặp sự cố với Danh sách .... – mrbradleyt

+0

Bạn không thực sự cần thuộc tính XmlArray nếu bạn sử dụng sgen. Mẫu chung là lấy một lớp riêng biệt từ Danh sách và sau đó tuần tự hóa thay vì ví dụ: [Serializable] public class YourObjectCollection: Danh sách {} Tuy nhiên, tôi đã phát hiện ra rằng thậm chí đó không phải là cần thiết – ilitirit

+0

1 ilitirit. Cố định một vấn đề gây phiền nhiễu tôi đã có nơi tôi không thể serialize một danh sách mà không nhận được một bộ thêm các thẻ gói nó, vì vậy tôi không thể ReadXml nó vào một DataSet. –

1

Bạn sẽ gặp vấn đề với việc sắp xếp bộ sưu tập nếu các đối tượng trong bộ sưu tập chứa bất kỳ tham chiếu nào đến các đối tượng khác trong cùng một bộ sưu tập. Nếu bất kỳ loại điểm kép nào tồn tại, bạn sẽ tạo ra một bản đồ đa không thể được tuần tự hóa. Trên mọi vấn đề tôi đã từng sắp xếp một bộ sưu tập tùy chỉnh, nó luôn luôn là do một số chức năng bổ sung mà tôi cần làm việc tốt như một phần của ứng dụng máy khách "điển hình", và sau đó thất bại thảm hại như một phần của nhà cung cấp người tiêu dùng ứng dụng máy chủ.

3

Nếu tôi nhớ lại nó hoạt động như thế này với một tài sản:

[XmlArray("Foo")] 
[XmlArrayItem("Bar")] 
public List<BarClass> FooBars 
{ get; set; } 

Nếu bạn đăng này, bạn sẽ nhận được một cái gì đó như:

<Foo> 
    <Bar /> 
    <Bar /> 
</Foo> 

Tất nhiên, tôi có lẽ nên hoãn đến Các chuyên gia. Dưới đây là thông tin khác từ MS: http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlarrayitemattribute.aspx

Hãy cho tôi biết nếu điều đó phù hợp với bạn.

1

Đặt tất cả các lớp bạn muốn tuần tự hóa vào một hội đồng riêng biệt, và sau đó sử dụng công cụ sgen để tạo một hội đồng tuần tự hóa để tuần tự hóa thành XML. Sử dụng các thuộc tính XML để kiểm soát tuần tự hóa.

Nếu bạn cần tùy chỉnh hội đồng tuần tự hóa (và bạn sẽ cần điều đó để hỗ trợ các lớp không phải là IXmlSerializable và các lớp chứa nút trừu tượng), sau đó hướng dẫn sgen kết xuất mã nguồn vào một tệp riêng biệt thêm nó vào giải pháp của bạn. Sau đó, bạn có thể sửa đổi nó khi cần thiết.

http://msdn.microsoft.com/en-us/library/bk3w6240(VS.80).aspx

FWIW, tôi đã quản lý để serialize toàn bộ AdsML Framework (hơn 400 lớp) sử dụng kỹ thuật này. Nó đã yêu cầu rất nhiều tùy chỉnh bằng tay, nhưng không có xung quanh rằng nếu bạn xem xét kích thước của khuôn khổ. (Tôi đã sử dụng một công cụ riêng để đi từ XSD C#)

0

Có lẽ một con đường hiệu quả hơn sẽ được serialize sử dụng BinaryFormatter

Như sao chép từ http://blog.paranoidferret.com/index.php/2007/04/27/csharp-tutorial-serialize-objects-to-a-file/

using System.IO; 
using System.Runtime.Serialization; 
using System.Runtime.Serialization.Formatters.Binary; 

public class Serializer 
{ 
    public Serializer() 
    { 
    } 

    public void SerializeObject(string filename, 
        ObjectToSerialize objectToSerialize) 
    { 
     Stream stream = File.Open(filename, FileMode.Create); 
     BinaryFormatter bFormatter = new BinaryFormatter(); 
     bFormatter.Serialize(stream, objectToSerialize); 
     stream.Close(); 
    } 

    public ObjectToSerialize DeSerializeObject(string filename) 
    { 
     ObjectToSerialize objectToSerialize; 
     Stream stream = File.Open(filename, FileMode.Open); 
     BinaryFormatter bFormatter = new BinaryFormatter(); 
     objectToSerialize = 
     (ObjectToSerialize)bFormatter.Deserialize(stream); 
     stream.Close(); 
     return objectToSerialize; 
    } 
} 
0

Để có khả năng tương tác, chúng tôi luôn sử dụng Xml Serialization và đảm bảo rằng lớp học của chúng tôi được thiết kế từ đầu để làm điều đó một cách chính xác.

Chúng tôi tạo một tài liệu lược đồ XSD và tạo một tập các lớp từ đó bằng cách sử dụng XSD.exe. Điều này tạo ra các lớp một phần để chúng ta tạo một tập các lớp phần tương ứng để thêm các phương thức bổ sung mà chúng ta muốn giúp chúng ta điền vào các lớp và sử dụng chúng trong ứng dụng của chúng ta (vì chúng tập trung vào serialising và deserialising.).

0

Bạn nên sử dụng NetDataContractSerializer.Nó bao gồm bất kỳ loại đồ thị đối tượng và hỗ trợ generics, danh sách, đa hình (thuộc tính KnownType là không cần thiết ở đây), đệ quy và vv Hạn chế duy nhất là bạn phải đánh dấu tất cả các lớp học với thuộc tính [Serializable]/[DataContract] , nhưng kinh nghiệm cho thấy rằng bạn phải làm một số loại tinh chỉnh thủ công anyway vì không phải tất cả các thành viên nên được tiếp tục tồn tại. Ngoài ra nó nối tiếp thành một Xml, mặc dù khả năng đọc của nó là vấn đề.

Chúng tôi đã có các yêu cầu tương tự như của bạn và đã chọn giải pháp này.

1

Tôi đồng ý rằng các phương pháp tuần tự dựa trên DataContract (với JSON, XML, v.v.) phức tạp hơn một chút so với tôi muốn.

Nếu bạn đang cố gắng để có được JSON kiểm tra http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx

Đó là một phần của các phần mở rộng MS AJAX. Phải thừa nhận rằng nó được gắn cờ là lỗi thời trong .NET 3.5 nhưng ScottGu đề cập trong bình luận blog của anh ấy ở đây (http://weblogs.asp.net/scottgu/archive/2007/10/01/tip-trick-building-a-tojson-extension-method-using-net-3-5.aspx#4301973) rằng anh ấy không chắc chắn tại sao và nó nên được hỗ trợ lâu hơn một chút.

Các vấn đề liên quan