问题
I have this code, and when i'm executing it this keeps showing the same error: Invalid JSON primitive: titles.
Client Side:
var title = new Array();
...
for (var i = 0; i < names.length; ++i) {
title[i] = '{ "titulo' + i + ':"' + names[i] + '"}';
}
$("#gif").show();
$.ajax({
async: true,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
type: "POST",
data: { titles: title },
url: "../handlers/saveUpload.ashx",
success: function (msg) {
$("#gif").hide();
}
});
Server Side:
context.Response.ContentType = "application/json";
var data = context.Request;
var sr = new StreamReader(data.InputStream);
var stream = sr.ReadToEnd();
var javaScriptSerializer = new JavaScriptSerializer();
var arrayOfStrings = javaScriptSerializer.Deserialize<string[]>(stream);
foreach (var item in arrayOfStrings)
{
context.Response.Write(item);
}
Regards
回答1:
Solved in this post: convert array to json and receive in ashx handler
string[] is not a valid generic type for that operation; string doesn't have a parameterless constructor so when the serialiser tries to new one up, it fails. Besides, you already have a string from sr.ReadToEnd() so you're not really deserialising, it's more like you are asking it to parse and split the string for you, which it can't do.
JavaScriptSerializer is pretty unforgiving and to be honest I always end up tearing my hair out when trying to deserialise an array like this...you are much better off defining a DTO class on the server side to handle the mapping:
[Serializable]
public class Titles
{
public List<Title> TheTitles { get; set; }
}
[Serializable]
public class Title
{
public string title { get; set; }
}
So now your handler looks like this:
public void ProcessRequest(HttpContext context)
{
try
{
context.Response.ContentType = "application/json";
var data = context.Request;
var sr = new StreamReader(data.InputStream);
var stream = sr.ReadToEnd();
var javaScriptSerializer = new JavaScriptSerializer();
var PostedData = javaScriptSerializer.Deserialize<Titles>(stream);
foreach (var item in PostedData.TheTitles )
{
//this will write SteveJohnAndrew as expected in the response
//(check the console!)
context.Response.Write(item.title);
}
}
catch (Exception msg) { context.Response.Write(msg.Message); }
}
And your AJAX is like this:
function upload()
{
//example data
var Titles = [
{'title':'Steve'}, {'title':'John'}, {'title':'Andrew'}
];
var myJSON = JSON.stringify({ TheTitles: Titles });
console.log(myJSON);
$.ajax({
async: true,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
type: "POST",
data: myJSON,
url: "jsonhandler.ashx",
success: function (msg) {
console.log(msg);
}
});
}
Note how the definition of the DTO classes matches exactly the definition of the JSON object properties, if it doesn't then the deserialisation will not work.
Hope that helps.
回答2:
Just to add a more visible comment to Diogo's answer, which is correct, but in my case needed the addition of JsonProperty
on the List of children in the parent class"
[Serializable]
public class Titles
{
[JsonProperty("Titles")]
public List<Title> TheTitles { get; set; }
}
来源:https://stackoverflow.com/questions/19809791/send-json-array-to-ashx-handler