0

我在 WebApi 控制器中编写了以下操作:

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

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

4

3 回答 3

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,
       };
于 2013-03-15T12:45:09.203 回答
0

双引号被转义。这既是预期的也是期望的行为——它可以防止字符串(如保存 JSON 数据的字符串)过早关闭。

于 2013-03-15T12:45:45.910 回答
0

Json()为什么不直接使用为您构建结果对象的内置方法?

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

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

    return Json(item);
}

如果您需要详细控制序列化的完成方式,您可以创建自己的JsonResult类版本并覆盖Execute(). 该帖子还建议为您的控制器创建一个覆盖该Json()方法的基类,但我宁愿创建一个扩展方法Controller- 一方面,这不会对您的控制器提出任何基类要求,另一方面如果您需要它,它不会隐藏默认行为:

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

这个答案(与上述相同的问题)似乎完全完成了您正在做的事情 - 选择一个可以处理数据协定属性的 JSON 序列化程序。

于 2013-03-15T13:21:49.560 回答