2013-03-15 80 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序列,可以处理数据合约属性。

相关问题