将JSON格式的字符串传递给使用JSON.NET的服务器的ajax调用

时间:2016-08-12 13:13:30

标签: javascript jquery json ajax json.net

我有一个JSON字符串被发送到服务器。该字符串已经是JSON格式。为什么我必须再次调用JSON.stringify才能将其成功发送到服务器?成功意味着服务器命中并显示值,但现在似乎JSON.stringify完成了两次。这在服务器上解析时会造成麻烦吗?我在这做错了什么?为什么我不能只发送JSON字符串?

以下是带有ajax调用的代码

    var listsJS = this.ConvertSummaryToJSON(); // Summary Page converted to json string
    $.ajax({
        type: "POST",
        //dataType: "JSON",
        contentType: "application/json",
        async: true,
        data: JSON.stringify({ "summary": listsJS }),
        url: GetHelper().GetVirtualDirectoryUrl() + "Reports/GenerateExcelReport"
    }).done((data) => {
        console.log(data);
    }).fail(function () {
        console.log('Failed to send');
    });

this.ConvertSummaryToJSON()返回看起来像这样的实际JSON字符串。

{
    "Summary": [{
        "NewBillers": []
    }, {
        "Bench": [{
            "FirstName": "Thomas",
            "LastName": "Train"
        }]
    }, {
        "SixtyDayRollOffs": [{
            "FirstName": "Michael",
            "LastName": "James"
        }]
    }, {
        "CurrentUnassignedEmployees": [{
            "Name": "Fly, Dan",
            "EmployeeTitle": "Practice Director"
        }]
    }, {
        "TotalSummaryCounts": [{
            "BenchHours": "1316",
            "EffectiveBench": "29",
            "Contributors": "37",
            "FourtyHourContributors": "14",
            "AvailableBench": "26",
            "EffectiveBillers": "79.533333"
        }]
    }]
}

如果我按照我的方式进行ajax调用,它会命中服务器,但JSON字符串将如下所示

"{\"Summary\":[{\"NewBillers\":[]},{\"Bench\":[{\"FirstName\":\"Thomas\",  \"LastName\":\"Train\", \......."

如果我使用JSON.NET的

解析它

JObject obj = (JObject)JsonConvert.DeserializeObject(string)

我回到了我开始的地方。使用JSON字符串,但表示为JObject。 这个JObject只有一个值,它是我开始使用的原始JSON字符串。

所以我搞砸了发送它的地方。它应该作为JSON字符串发送,而不是JSON字符串的JSON.stringify()版本。

我正在改变ajax调用只有

data: {"summary": listsJS}

但这会导致服务器抛出响应为500 Internal Server error

Invalid JSON primitive: summary

如何直接从listsJS传递JSON字符串,而不必再次JSON.stringify()将其传递给服务器?

如果我只使用data: listsJS,那么它将命中服务器,但服务器上方法中的参数将收到空值。

这是服务器代码的样子,也许它会有所帮助。

public ActionResult GenerateExcelReport(string summary)
{
    var a = ExportUtility.CreateExcelSheet(summary); // <-- this just returns a literal string "Message from server"
    return Json(a, JsonRequestBehavior.AllowGet);
}

2 个答案:

答案 0 :(得分:0)

我非常确定我是否正确理解了您的所有问题,但我们继续:

(1){ foo: "bar" } NOT 是一个JSON字符串。它是一个JavaScript对象。这是核心应用JSON表示'{"foo":"bar"}'。它们看起来非常相似,因为(我想你知道,但只是为了确定)JSON代表JavaScriptObjectNotation。它只是以“字符串”形式表示的惯例。

(2)使用$.ajax时,不必对对象进行字符串化。正如documentation状态:它将“转换为查询字符串,如果还不是字符串”。这意味着它最终会以XHR的形式数据作为字符串结束。

(3)您(或jQuery)为您对象进行字符串化的原因是HTTP协议是基于文本的。否则,使用不同的技术很难使用它。因此,您的服务器只获取“文本消息”,并且必须将表单数据解析回其理解的任何符号(以及其他数据,例如告知接收方XHR这是一个POST)。

答案 1 :(得分:0)

你的问题中有一些不清楚的事情,但我会在这里猜测并说你的对象得到JSON.stringify两次。

您发布的this.ConvertSummaryToJSON()返回值看起来像JavaScript 对象而不是JSON字符串但我认为这是一个错误,因为对象键看起来像它是字符串化的。

事情就是这样,当您与data: JSON.stringify({ 'summary': listsJS })进行ajax通话时,您传递给JSON.stringify的对象包含一个键summary listsJS指向的字符串值。当序列化,发送到您的服务器并反序列化时,结果与您发送的内容相同:字符串!如果您再次对该字符串进行反序列化,那么您将拥有所需的对象。

仅仅使用data: {"summary": listsJS}不会出于同样的原因,你发送一个字符串并且jQuery无法知道该字符串是一个JSON序列化对象,所以它会很乐意为你序列化该字符串。

您需要做的是只返回this.ConvertSummaryToJSON函数中的相关对象而不是JSON字符串。然后,您可以使用data: { 'summary': listsJS }发送数据。

希望这会有所帮助。