2014-04-29 16 views
10

Hy vọng đây là một sửa chữa dễ dàng mà tôi đã bỏ qua. Tôi có một đối tượng được truyền vào phương thức thụ lý sự kiện mà tôi muốn serialize đối tượng sử dụng JSON.NET, như vậy:JSON.NET Tuần tự hóa trên một đối tượng có thành viên thuộc loại Stream?

public void OnEvent(IEventObject foo) 
{ 
    // Serialize foo to string/disk here? 
    var data = JsonConvert.SerializeObject(foo, Formatting.Indented); 
} 

Dường như một hoặc nhiều thành viên foo của những con suối. Tôi đã nhận ra rằng các luồng không thể tuần tự hóa được vì chúng là một sự trừu tượng hóa dữ liệu chứ không phải dữ liệu. Điều này thật ý nghĩa.

Tôi không biết làm thế nào để serialize đối tượng này anyway bởi một trong hai:

  • a) Chuyển đổi các luồng lại thành dữ liệu và serializing rằng
  • b) Bỏ qua những con suối và serialize các thành viên còn lại

Một lưu ý lớn cho điều này là tôi không có quyền truy cập vào IEventObject hoặc việc triển khai IEventObject của nó, vì vậy tôi không thể đánh dấu bất kỳ đối tượng nào có cờ thuộc tính.

Giải pháp duy nhất tôi đã đưa ra là để bọc đối tượng này trong lớp của riêng tôi, đánh dấu nó một cách thích hợp và sắp xếp thứ tự đó. Sau đó tôi sẽ deserialize trở lại vào lớp học của riêng tôi, và chuyển đổi nó thành đối tượng ban đầu. Tôi không thích cách tiếp cận này vì nó liên quan đến một đối tượng phụ và bước chuyển đổi, và muốn tránh nó nếu có thể.

+1

Tôi phải đối mặt với cùng một vấn đề và không có sự lựa chọn nào khác ngoài việc bọc nó trong một đối tượng của tôi hoàn toàn có thể tuần tự hóa được. nếu có một lựa chọn khác, tôi sẽ rất vui khi nghe nó :-) –

+0

@Bartdude bạn có thể xem câu trả lời của tôi. –

+0

@TimS. Thật không may trong trường hợp của tôi, tôi đã kết thúc việc phải thực hiện các đối tượng wrapper vì tôi không có quyền truy cập cục bộ vào các kiểu cụ thể để deserialize trở lại. Nếu không, câu trả lời được chấp nhận là một giải pháp tuyệt vời cho vấn đề này. – jmsb

Trả lời

13

Theo mặc định, Json.NET sẽ cố gắng tuần tự hóa các thuộc tính của luồng, vốn không hữu ích lắm. Bạn có thể sửa đổi hành vi bằng cách tạo của riêng bạn contract resolver. Dưới đây là một ví dụ mà bỏ qua tất cả Stream s hoàn toàn:

public class IgnoreStreamsResolver : DefaultContractResolver 
{ 
    protected override JsonProperty CreateProperty(
     MemberInfo member, 
     MemberSerialization memberSerialization 
    ) 
    { 
     JsonProperty property = base.CreateProperty(member, memberSerialization); 
     if (typeof(Stream).IsAssignableFrom(property.PropertyType)) 
     { 
      property.Ignored = true; 
     } 
     return property; 
    } 
} 

sử dụng nó như:

var bytes = new byte[] { 1, 2, 3 }; 
var eo = new EventObject { OtherValue = 2, MyStream = new MemoryStream(bytes) }; 
var s = JsonConvert.SerializeObject(eo, 
    new JsonSerializerSettings { ContractResolver = new IgnoreStreamsResolver() }); 
// {"OtherValue":2} 

Bằng cách thay đổi các thuộc tính khác của JsonProperty, bạn có thể thực hiện thay đổi khác. Hình ảnh có vẻ hữu ích nhất đối với bạn là Converter, điều này sẽ cho phép bạn chỉ định lớp của riêng bạn để xác định cách tuần tự hóa Stream (ví dụ: chuyển đổi thành số byte[] và tuần tự hóa làm base64).

Tất cả điều này được thực hiện mà không có bất kỳ thay đổi nào đối với giao diện hoặc lớp triển khai.

+0

Đây chính xác là những gì tôi đang tìm kiếm. Tôi sẽ kiểm tra lại sau khi triển khai và tự mình kiểm tra. Cảm ơn. – jmsb

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