简体   繁体   中英

Passing in string in JSON format to ajax call to server with JSON.NET

I have a JSON string being sent to a server. The string is already in JSON format. Why do I have to call JSON.stringify again to have it sent successfully to the server? Successfully meaning the server hits and the value appears, but now it seems like JSON.stringify is done twice. This causes trouble when parsing it on the server? What am I doing wrong here? Why can't I just send in the JSON string?

Here is the code with the ajax call

    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() return the actual JSON string that looks something like this.

{
    "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"
        }]
    }]
}

If I make the ajax call like I did, it'll hit the server, but the JSON string will look like this

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

If I parse this, using JSON.NET's

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

I am back where I begin. With a JSON string, but represented as a JObject. This JObject has only one value, and it's the original JSON string that I started with.

So I'm messing up where I'm sending it. It should be sent at as a JSON string, not a JSON.stringify() version of a JSON string.

I've altering the ajax call to just have

data: {"summary": listsJS}

but this causes the server to throw a 500 Internal Server error with a response of Invalid JSON primitive: summary

How can I just pass in the JSON string straight from listsJS without having to JSON.stringify() it again to pass it to the server?

If I use just data: listsJS then it will hit the server, but the parameter in the method on the server will receive a null value.

Here is what the server code looks like, maybe it'll help.

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

I note quite sure if I understood all your questions correctly, but here we go:

(1) { foo: "bar" } is NOT a JSON string. It's a JavaScript Object. This is the coreesponding JSON representation '{"foo":"bar"}' . They both look very similar because (I think you know that, but just to be sure) JSON stands for JavaScriptObjectNotation. It is just a convention for representing in a "string" form.

(2) You do not have to stringify your object when you use $.ajax . As the documentation states: it will be "converted to a query string, if not already a string." Meaning it will end up in the form data of your XHR as a string anyway.

(3) The reason you (or jQuery) stringifies the object for you is that the HTTP-Protocol is text-based. Otherwise it would be hard to use it with different technologies. So your server only gets a "text message" and has to parse the form data back to whatever notation it understands (together with additional data that for example tells the receiver of the XHR that this is a POST).

There are some unclear things in your question but I'm going to take a guess here and say that your object is getting JSON.stringify d twice.

The this.ConvertSummaryToJSON() return value you posted looks like a JavaScript object not a JSON string but I assume that was a mistake because the object keys do look like it was stringified.

So here's the thing, when you're making an ajax call with data: JSON.stringify({ 'summary': listsJS }) , the object you have passed to JSON.stringify contains a key summary with a string value pointed to by listsJS . When this is serialized, sent to your server and deserialized, the result is the same thing you sent: a string! If you were to deserialized that string once again you would have your required object.

Just using data: {"summary": listsJS} will not work for the same reason, you are sending a string and jQuery has no way of knowing that that string is a JSON serialized object, so it will happily serialize that string for you.

What you need to do is to just return the relevant object from your this.ConvertSummaryToJSON function instead of a JSON string. You can then send the data with data: { 'summary': listsJS } .

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM