为什么JsonResult返回改变后的Json(带"而不是")

本文关键字:quot 返回 JsonResult 改变 Json 为什么 | 更新日期: 2023-09-27 18:04:18

我在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。序列化(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'"},

注意文本中的'"。为什么会这样呢?如何改变它?我想不通……

EDITJsonSerializer JsonSerializer是我的helper类,它使用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;
    }
}

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

为什么JsonResult返回改变后的Json(带"而不是")

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

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

为什么不直接使用内置的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序列化器。

相关文章: