我在WebApi控制器中编写了以下Action:
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,item);
将数据序列化为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;
}
}
我想要的是它的执行结果 - 并且没有被更改 - 返回给用户
答案 0 :(得分:4)
JsonResult
已经将Data
内的任何内容序列化为JSON。
在设置Data
之前,您的代码会手动序列化为JSON,这会导致包含双序列化对象的输出(item
首先手动序列化为JSON字符串,然后字符串为再次使用JSON规则序列化 - 这是第二个序列化,它可以转义你的引号。)
虽然从技术上讲我们不能排除双序列化是故意进行的可能性,但很可能你应该做的是
var jsonResult = new JsonResult
{
ContentType = "application/json",
Data = item,
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
};
如果您不想序列化两次但需要手动序列化,请改用ContentResult
:
return new ContentResult
{
ContentType = "application/json",
Content = serializedData,
};
答案 1 :(得分:0)
双引号被转义。这是预期和期望的行为 - 它保持字符串(如保存JSON数据的字符串)提前关闭。
答案 2 :(得分: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序列化程序。