2013-03-15 83 views
0

我有以下動作寫入到的WebAPI控制器:爲什麼JsonResult返回改變的Json(用「而不是」)?

public JsonResult GetData() 
    { 
     _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

     var item = new Item(); 
     item.GenerateData(); 

     var jsonMediaTypeFormatter = new JsonMediaTypeFormatter 
      { 
       UseDataContractJsonSerializer = true 
      }; 


     var jsonSerializer = new JsonSerializer(); 

     var serializedData = jsonSerializer.Serialize(jsonMediaTypeFormatter, item); 

     var jsonResult = new JsonResult 
     { 
      ContentType = "application/json", 
      Data = serializedData, 
      JsonRequestBehavior = JsonRequestBehavior.AllowGet, 
     }; 

     return jsonResult; 
    } 

線: VAR serializedData = jsonSerializer.Serialize(jsonMediaTypeFormatter,項目);

串行化數據爲JSON因此我有:

{"Class":{"Valid":{"From":"\/Date(1363302000000+0100)\/","To":"\/Date(43017433200000+0100)\/"},"Code":3,"Id":3,"Name":"Class3"}, 

等..(不是一個完整的JSON)

而是由JsonResult返回的JSON是不同:

{"ContentEncoding":null,"ContentType":"application\/json","Data":"{\"Class\":{\"Valid\":{\"From\":\"\\\/Date(1363302000000+0100)\\\/\",\"To\":\"\\\/Date(43017433200000+0100)\\\/\"},\"Code\":3,\"Id\":3,\"Name\":\"Class3\"}, 

\「在文中。 爲什麼是這樣?如何改變它?我無法弄清楚..

編輯JsonSerializer JsonSerializer是我的助手類,它使用DataContractJsonSerializer其代碼如下序列化數據到JSON:

public class JsonSerializer 
{ 
    public string Serialize<T>(MediaTypeFormatter formatter, T value) 
    { 
     // Create a dummy HTTP Content. 
     Stream stream = new MemoryStream(); 
     var content = new StreamContent(stream); 

     // Serialize the object. 
     formatter.WriteToStreamAsync(typeof(T), value, stream, content, null).Wait(); 

     // Read the serialized string. 
     stream.Position = 0; 
     return content.ReadAsStringAsync().Result; 
    } 
} 

我想擁有的是其執行的結果 - 並沒有被改變 - 返回給用戶

回答

4

JsonResult已經將您在Data中放入的任何內容序列化爲JSON。

您的代碼手動序列化爲JSON設定Data,這導致在含雙序列化對象的輸出(item是第一手動序列化到JSON字符串,則該字符串是再次使用JSON規則序列之前 - 它這是第二個序列化,是逃避你的報價)。

雖然在技術上,我們不能排除,雙串行化是故意的可能性,最有可能的,你應該做的事情是

var jsonResult = new JsonResult 
    { 
     ContentType = "application/json", 
     Data = item, 
     JsonRequestBehavior = JsonRequestBehavior.AllowGet, 
    }; 

如果你不想序列化兩次,但需要手動序列化然後使用ContentResult代替:

return new ContentResult 
     { 
      ContentType = "application/json", 
      Content = serializedData, 
     }; 
+0

我忘了補充。我需要使用DataContractJsonSerializer序列化數據,然後如何讓它序列化呢? – lixonn 2013-03-15 12:47:41

+1

@ lukasz.pek:我已經更新了相應的答案。 – Jon 2013-03-15 12:50:40

+0

不錯,謝謝,但我對結果還是不滿意(看看編輯過的問題) – lixonn 2013-03-15 13:06:01

0

雙引號會被轉義。這既是預期的行爲也是期望的行爲 - 它使得字符串(比如保存JSON數據的字符串)不被提前關閉。

0

爲什麼不使用內置的Json()方法,該方法會爲您構建結果對象?

public JsonResult GetData() 
{ 
    _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

    var item = new Item(); 
    item.GenerateData(); 

    return Json(item); 
} 

如果需要的序列化是如何完成的,你可以create your own version of the JsonResult class and override Execute()詳細的控制。這篇文章還建議爲您的控制器創建一個基類,以覆蓋Json()方法,但我寧願在Controller上創建擴展方法 - 一方面,這不會在基類中對您的控制器提出任何要求,並且另一個不隱藏默認的行爲,如果你需要它:

public static class ControllerExtensions 
{ 
    public static JsonResult DataContractJson(this Controller ctrl, object data) { 
     return new DataContractJsonResult { Data = data }; 
    } 
} 

This answer(對同一問題,如上圖所示),似乎完成你在做什麼 - 選擇一個JSON序列,可以處理數據合約屬性。

相關問題