【问题标题】:JSON Response Contains Extra CharactersJSON 响应包含额外字符
【发布时间】:2016-08-07 16:27:32
【问题描述】:

我使用 Nancy 创建了一个服务来进行数据库查找并以 JSON 形式返回结果。这是测试代码:

using (var dt = new DataTable("MyData"))
{
    dt.Columns.Add("id");
    dt.Columns.Add("password");
    dt.Columns.Add("body", System.Type.GetType("System.String"));
    dt.Columns.Add("balance", System.Type.GetType("System.Double"));
    dt.Rows.Add(uid, pwd, "Some useful content", 33.75);
    dt.Rows.Add(uid, pwd, "More useful content", 128.55);
    if (dotNetDataTable)
        json = JsonConvert.SerializeObject(dt, new Serialization.DataTableConverter());
    else
        json = JsonConvert.SerializeObject(dt);
    json = "{\"status\":\"success\",\"data\":" + json + "}";
    return Response.AsJson(json);
}

在返回之前中断进程,并轮询json的值,我得到:

"{\"status\":\"success\",\"data\":[{\"id\":\"RMittelman\",\"password\":\"Password\",\"body\":\"Some useful content\",\"balance\":33.75},{\"id\":\"RMittelman\",\"password\":\"Password\",\"body\":\"More useful content\",\"balance\":128.55}]}"

这在即时窗口中似乎是正确的。当我收到数据并中断进程时,我会在客户端即时窗口中看到:

"\"{\\\"status\\\":\\\"success\\\",\\\"data\\\":[{\\\"id\\\":\\\"RMittelman\\\",\\\"password\\\":\\\"Password\\\",\\\"body\\\":\\\"Some useful content\\\",\\\"balance\\\":33.75},{\\\"id\\\":\\\"RMittelman\\\",\\\"password\\\":\\\"Password\\\",\\\"body\\\":\\\"More useful content\\\",\\\"balance\\\":128.55}]}\""

如您所见,其中包含额外的前导引号和尾随引号,以及一堆额外的反斜杠。 JSON 不会反序列化。这是客户端文本框中显示的结果:

json result:
"{\"status\":\"success\",\"data\":
[{\"id\":\"RMittelman\",\"password\":\"Password\",\"body\":\"Some useful content\",\"balance\":33.75},
{\"id\":\"RMittelman\",\"password\":\"Password\",\"body\":\"More useful content\",\"balance\":128.55}]}"

Unexpected JSON token when reading DataTable. Expected StartArray, got String. Path '', line 1, position 240.

如果我以编程方式删除前导引号和尾随引号以及所有反斜杠,它就可以正常工作。 这是我在客户端用来获取数据的代码:

string GET(string url)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    try
    {
        WebResponse response = request.GetResponse();
        using (Stream responseStream = response.GetResponseStream())
        {
            StreamReader reader = new StreamReader(responseStream, Encoding.UTF8);
            string responseText = reader.ReadToEnd();
            isError = false;
            return responseText;
        }
    }
    catch (WebException ex)
    {
        isError = true;
        WebResponse errorResponse = ex.Response;
        if (errorResponse == null)
            return ex.Message;
        using (Stream responseStream = errorResponse.GetResponseStream())
        {
            StreamReader reader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
            String errorText = reader.ReadToEnd();
            return errorText;
        }
        throw;
    }
}

那么问题来了,为什么在发送前看起来没问题,但发送后包含所有垃圾?

【问题讨论】:

  • 看起来您正在沿途某处对 JSON 字符串进行双重编码。删除一级 JSON 编码。
  • 这让我很困惑。就在从服务返回原始 JSON 字符串之前的第一个即时窗口结果看起来是正确的。我知道它显示引号和斜线,但这是一个直接的窗口,对吧?这是第二个,收到后,有所有额外的数字。我没有编写 .Net 代码来发布和接收,从谷歌得到它。但它似乎不包含任何 JSON 编码。我不知道为什么在返回响应之前它看起来还可以,但在收到后却有额外的垃圾。是否可能发生某种字符编码的事情?
  • 您正在对 JSON 进行双重序列化。 (将类序列化为 JSON,然后将 JSON 序列化为字符串文字。)请参阅 stackoverflow.com/questions/7597035/…stackoverflow.com/questions/33983600/…
  • 这不是垃圾,这就是双编码的样子。就像"&" 在 HTML 中变成 "&" 和在双编码 HTML 中变成 "&" 一样。 .NET Web 方法很可能已配置为返回 JSON。因此,您无需进行任何手动 JSON 序列化,只需返回数据本身即可。
  • 谢谢@Tomalak。我在做:json=JsonConvert.SerializeObject,然后:Return Response.AsJson(json)。 code 你的双重序列化。第一次使用json。菜鸟失误。如果我知道如何为 cmets 提供信用,我会给你信用。

标签: json json.net nancy


【解决方案1】:

JSON 被双重编码。代码是:

json=JsonConvert.SerializeObject(dataTable);

然后

return Response.AsJson(json);

改成:

return (Response)json;

问题就解决了。谢谢大家的意见!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多