为什么JsonResult返回改变的Json(用“而不是”)?

时间:2013-03-15 12:42:46

标签: c# asp.net-mvc json serialization

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

我想要的是它的执行结果 - 并且没有被更改 - 返回给用户

3 个答案:

答案 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序列化程序。