2011-08-21 24 views
6

Có thể nhận ServiceStack JsonSerializer để tuần tự hóa ExpandoObject làm đối tượng phẳng thay vì từ điển không? Một cái gì đó khoảng xấp xỉ này:Làm thế nào để tuần tự hóa ExpandoObject bằng ServiceStack JsonSerializer?

{"x":"xvalue","y":"\/Date(1313966045485)\/"} 

Tôi cố gắng để so sánh JSON serialization của ExpandoObject sử dụng ba hệ thống khác nhau: NET BCL JavaScriptSerializer, Newtonsoft JSON.NET, và JSON chào ServiceStack của.

Tôi bắt đầu với một đối tượng động đơn giản.

dynamic test = new ExpandoObject(); 
test.x = "xvalue"; 
test.y = DateTime.Now; 

Dường như đơn giản hơn để bộ nối tiếp xử lý ExpandoObject là IDictionary<string, object>. Cả BCL và ServiceStack đều bắt đầu theo cách này, mặc dù đi các tuyến đường khá khác nhau với kết quả.

JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer(); 
Console.WriteLine(javaScriptSerializer.Serialize(test)); 
// [{"Key":"x","Value":"xvalue"},{"Key":"y","Value":"\/Date(1313966045485)\/"}] 

Console.WriteLine(ServiceStack.Text.JsonSerializer.SerializeToString(test)); 
// ["[x, xvalue]","[y, 8/21/2011 16:59:34 PM]"] 

Tôi muốn có ExpandoObject được tuần tự hóa nhiều hơn khi được lắp ráp trong mã, như lớp thông thường sẽ được đăng theo thứ tự. Bạn có thể add an override JavaScript serializer to the BCL system for IDictionary<string, object>. Điều này làm việc tuyệt vời, giả sử một không thực sự có một IDictionary<string, object> mà cần phải ở lại theo cách đó (mà tôi chưa).

JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer(); 
javaScriptSerializer.RegisterConverters(new JavaScriptConverter[] { new ExpandoJsonConverter() }); 
Console.WriteLine(javaScriptSerializer.Serialize(test)); 
// {"x":"xvalue","y":"\/Date(1313966045485)\/"} 

Thật không may, tôi vẫn cần một cách để có được JsonSerializer của ServiceStack để xử lý ExpandoObject theo cùng một cách. Làm thế nào để móc vào hệ thống ServiceStack để làm điều này có thể?

Cập nhật: Mặc dù đây không phải là tùy chọn để sử dụng, có vẻ như ServiceStack xử lý các đối tượng ẩn danh tốt.

Console.WriteLine(ServiceStack.Text.JsonSerializer.SerializeToString(new { x = "xvalue", y = DateTime.Now })); 
// {"x":"xvalue","y":"\/Date(1313980029620+0000)\/"} 

Trả lời

1

Không có bất kỳ móc sẵn trong JsonSerializer ServiceStack rằng bạn có thể cắm vào để thay đổi hành vi này nhưng tôi được hạnh phúc hơn để có một yêu cầu kéo nào đó hơn;)

Các lớp bạn sẽ cần phải thay đổi là:

  • JsWriter.cs (đường 223) - chèn mã để phát hiện một đối tượng expando và trả về một đại biểu mà viết đối tượng expando cách bạn muốn nó.
  • JsReader (Tuyến 42) - chèn mã để phát hiện một đối tượng expando và trả về một đại biểu để đọc nội dung của một chuỗi và deserialize nó trở lại vào một expando

Tôi tưởng tượng mã để đối phó với một đối tượng expando cũng tương tự như một cuốn từ điển, do đó bạn sẽ có thể sử dụng các lớp thực hiện từ điển để hướng dẫn bạn (ví dụ WriteDictionary.csDeserializeDictionary.cs)

Hãy sử dụng diễn đàn ServiceStack nếu bạn có bất cứ thắc mắc hơn/các vấn đề về điều này: https://groups.google.com/forum/#!forum/servicestack

+0

Nếu tôi có thể nhận MonoTouch sử dụng ServiceStack để deserialize JSON được tạo ra từ một trong các hệ thống khác, vấn đề cụ thể này sẽ không thực sự làm tổn thương tôi quá nhiều. Ngay cả khi tôi có thể làm việc xung quanh nó, tôi sẽ cố gắng để xem những gì tôi có thể làm để đặt cùng một số mã cho một yêu cầu kéo; nó sẽ là tốt đẹp để sử dụng ServiceStack trên cả hai đầu của dự án hiện tại của tôi. – patridge

+1

Chắc chắn, để có được ServiceStack làm việc trên MonoTouch bạn chỉ cần sử dụng công cụ xây dựng MonoTouch có sẵn tại: https: // github.com/ServiceStack/ServiceStack/tree/master/release/mới nhất/MonoTouch – mythz

+0

Điều đó thật dễ dàng. Tôi đã có nó và chạy trong một vài phút. Sẽ mất vài giây nếu tôi không phát lại các phím tắt trong MonoDevelop khi tôi đi. – patridge

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