2014-08-27 46 views
4

我有一個與Conference API project類似的項目(幾乎完全相同),它正在採用類似的方法來處理返回的CollectionJson內容。我很難設置ReadDocument(第30行)的Collection屬性,因爲它沒有任何setter。我可以通過以下操作改變在Web Api項目中閱讀JSON內容

public CollectionJsonContent(Collection collection) 
{ 
    var serializerSettings = new JsonSerializerSettings 
     { 
      NullValueHandling = NullValueHandling.Ignore, 
      Formatting = Newtonsoft.Json.Formatting.Indented, 
      ContractResolver = new CamelCasePropertyNamesContractResolver() 
     }; 
    collection.Version = "1.0"; 

    Headers.ContentType = new MediaTypeHeaderValue("application/vnd.collection+json"); 

    using (var writer = new JsonTextWriter(new StreamWriter(_memoryStream)){CloseOutput = false}) 
    { 
     //var readDocument = new ReadDocument(); {IReadDocument.Collection = collection}; 
     var serializer = JsonSerializer.Create(serializerSettings); 
     serializer.Serialize(writer,collection); 
     writer.Flush(); 
    } 
    _memoryStream.Position = 0; 
} 

雖然上面的代碼編譯並在一定程度上梳理了問題,但後來我又會有不能夠消耗JsonCollection內容在我的控制器單元的另一問題,迴避這個問題試驗。請看下面的單元測試代碼片段:

  using (var request = CreateRequest()) 
      {     
       var controller = new TestController(DataService) {Request = request}; 

       var temp = await controller.ListAsync(gridSearchData, sampleSearchData); 

       if ((temp is NotFoundResult) && (sampleCollection.Any())) 
       { 
        Assert.Fail("Controller did not return any result but query did"); 
       } 

       var json = await temp.ExecuteAsync(cancellationTokenSource); 



       var readDocument = json.Content.ReadAsAsync<ReadDocument>(new[] {new CollectionJsonFormatter()}, cancellationTokenSource).Result; 

     } 

因爲我沒有設置ReadDocument readDocument的集合屬性始終是空的,我無法閱讀其內容。 你如何在WEB API項目中異步讀取客戶端的JsonCollection內容?

要在Conference Web Apiauthors blog

回答

1

好吧,這已被修復。 Collection屬性現在可以再次設置。

我剛推release 0.7.0與此修復程序,一個重要的命名重構以及一個不錯的改進序列化,不寫出空集合。

請參閱release notes的變化(特別是命名爲包名和命名空間已經改變)

+0

確實很棒的工作和很好的更新。現在,我可以設置ReadDocument集合屬性。但有一個問題:爲什麼我會得到:「沒有MediaTypeFormatter可用於從內容讀取類型爲'ReadDocument'的對象當我運行json.Content.ReadAsAsync (new [] {new CollectionJsonFormatter()},cancellationTokenSource)時,媒體類型爲「application/vnd.collection + json」如上面的單元測試所述?你在測試你的控制器的時候在你的unittests中設置MediaTypeFormetter的位置? – MHOOS 2014-09-10 16:32:15

+0

@MHOOS我回復了你的電子郵件,詢問你是否可以寄給我一些示例代碼。單元測試的要點也可以工作。 – 2014-09-12 18:54:49

0

得到做法看的清晰圖片至於我從你的代碼中看到的,你不序列化ReadDocument對象,但只有一個屬性(Collection) ,然後嘗試將該值反序列化爲新的ReadDocument對象。

樣本ReadDocument應序列這樣

"{"Collection": [1,2,3,4,5] }" 

但是你序列集合,讓你獲得

"[1,2,3,4,5]" 

我推薦的替代類系列化這樣

class SerializableReadDocument 
{ 
    public Collection Collection { get; set; } 
} 

和像這樣更新你的序列化代碼

using (var writer = new JsonTextWriter(new StreamWriter(_memoryStream)){CloseOutput = false}) 
{ 
    var readDocument = new SerializableReadDocument() { Collection = collection }; 
    var serializer = JsonSerializer.Create(serializerSettings); 
    serializer.Serialize(writer, readDocument); 
    writer.Flush(); 
} 

但是,當您嘗試反序列化的輸出,因爲ReadDocument不具有可設置Collection屬性這不會解決你的問題,反序列化要麼失敗,或者以空Collection返回ReadDocument對象。如果你喜歡你的單元測試,你可以使用SerializableReadDocument

+0

正如我在這個問題說明你也提到「對自己反序列化不實際的關注,但我有因爲我無法設置Collection屬性(這用於舊版本的CollectionJson中的setter,但Glen Block軟件包所有者用新版本修改了它),我的ReadDocument集合屬性是空的,我的問題是:如何設置ReadDocument的Collection屬性,以便我可以擁有json.Content.ReadAsAsync (new [] {new CollectionJsonFormatter()},cancellationTokenSource).Result – MHOOS 2014-09-05 08:53:18

+0

從WebApiContrib.Collectio 0.6.2版開始nJson',你根本做不到。即使你設法使用反射來設置'Collection'屬性,你也不能使用newtonsoft json反序列化它,因爲它不會設置集合。可能的解決方法是; 1-使用以前的版本,2-將集合內容複製到'ReadDocument.Collection',3-使用'SerializableReadDocument'。使用'SerializableReadDocument',這是最簡單的方法。 – edokan 2014-09-05 12:49:14

+0

@edokan如果你使用類似JSON.NET的東西,它應該反序列化。只需將項目添加到集合中就沒有問題。如果這不起作用,人們根本無法使用圖書館。 – 2014-09-06 20:01:57

0

我正在研究這個問題,並且會在本週末提出一個有希望的解決方案,這個解決方案要麼是讓它成爲公共設置者,要麼讓setter成爲內部人員,並且擁有接受集合的公共ctor。

對不起。