2014-04-29 104 views
10

希望這是一個簡單的解決方案,我忽略了。我已經傳遞到了我想要序列使用JSON.NET該對象,像這樣的事件處理程序的對象:使用Stream類型成員的對象上的JSON.NET序列化?

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

看來,一個或多個Foo的成員是流。我已經認識到Streams不是可序列化的,因爲它們是對數據的抽象而不是數據本身。這是有道理的。

我不知道如何通過兩種反正序列化此對象:

  • 一)流轉換成數據和序列化
  • B)忽略流和序列化的其餘成員

對此的一個重要警告是我無法訪問IEventObject或其實現,所以我無法用屬性標記標記任何這些對象。

我想出的唯一解決方案是將這個對象封裝在我自己的類中,適當標記並序列化。後來,我將反序列化回我自己的類,並將其轉換爲原始對象。我不喜歡這種方法,因爲它涉及一個額外的對象和轉換步驟,並且如果可能的話,希望避免它。

+1

我面對的是相同的問題,別無選擇,只能將其包裝在我的完全可序列化的對象中。如果還有其他選擇,我會很高興聽到它:-) –

+0

@Bartdude你可以看看我的答案。 –

+0

@TimS。不幸的是,在我的情況下,我最終不得不實現包裝器對象,因爲我沒有本地訪問要反序列化的具體類型。否則,接受的答案是解決這個問題的好辦法。 – jmsb

回答

13

默認情況下,Json.NET會嘗試序列化流的屬性,這不是很有用。您可以通過創建自己的contract resolver來修改行爲。下面是忽略所有Stream一個示例S完全:

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; 
    } 
} 

這樣使用它:

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} 

通過修改JsonProperty的其他屬性,可以進行其他更改。看起來像它可能是最適合您使用的一個是Converter,這將讓你指定你自己的類來定義如何序列化Stream(例如,將其轉換爲byte[]和序列化爲base64)。

所有這些都是在沒有對接口或實現類進行任何更改的情況下完成的。

+0

這正是我所尋找的。我會在自己實施和測試之後再回來查看。謝謝。 – jmsb

相關問題