jquery ajax调用返回JSON解析错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10456240/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jquery ajax call return JSON parsing error
提问by hofnarwillie
I am using jquery to call an ajax wcf method that returns a list of objects as a JSON string. The JSON string looks like this when inspecting it in fiddler2 (in TextView):
我正在使用 jquery 调用一个 ajax wcf 方法,该方法将对象列表作为 JSON 字符串返回。在 fiddler2(在 TextView 中)检查时,JSON 字符串如下所示:
{"d":"[{\"ID\":\"6b2b8c62-31ce-4df2-982b-054ff5f6be72\",\"Name\":\"Carol\",\"Surname\":\"IrishWife\"},{\"ID\":\"d254740a-0a0f-4a1e-9e4f-0812227dd5af\",\"Name\":\"Willie\",\"Surname\":\"Le Roux\"},{\"ID\":\"660bf0dd-436a-4588-a9c0-19fd6fdcee23\",\"Name\":\"Emmas\",\"Surname\":\"Mum\"},{\"ID\":\"6b9403c5-b728-4e96-bcb1-203e7472eec3\",\"Name\":\"Owen\",\"Surname\":\"Lima\"},{\"ID\":\"d52c08fb-4418-4600-960f-243ff4443ee6\",\"Name\":\"Tim\",\"Surname\":\"Lee\"},{\"ID\":\"e2aacf5b-8855-44ce-9338-3d39f8ab3349\",\"Name\":\"Marcello\",\"Surname\":\"MT\"},{\"ID\":\"578be087-8385-46d6-89de-3db31d352cbc\",\"Name\":\"Carlyn\",\"Surname\":\"Homegroup\"},{\"ID\":\"4c805825-2bee-447a-8b75-41ead17db33e\",\"Name\":\"George\",\"Surname\":\"Homegroup\"},{\"ID\":\"ae48804f-5e78-42c8-9ba0-4214c98a5a89\",\"Name\":\"Isla\",\"Surname\":\"Le Roux\"},{\"ID\":\"f8be2f4f-fedb-4863-8a84-44fddea84ea9\",\"Name\":\"Peter\",\"Surname\":\"Anderson\"},{\"ID\":\"15e7644d-ec43-44ff-a959-47e00112da6b\",\"Name\":\"Kitty\",\"Surname\":\"Corbett\"},{\"ID\":\"8fd7fccc-335c-4d5c-93b5-4b00f96a9950\",\"Name\":\"Natalie\",\"Surname\":\"Archibald\"},{\"ID\":\"09b5aad2-2cf1-488a-962b-4d692b05ddea\",\"Name\":\"Miku\",\"Surname\":\"Heally\"},{\"ID\":\"affa369e-5af3-4537-a0f4-71422956da41\",\"Name\":\"Steven\",\"Surname\":\"Corbett\"},{\"ID\":\"65f57da3-4f88-4798-9590-83b4ccecfc44\",\"Name\":\"Tim\",\"Surname\":\"Archibald\"},{\"ID\":\"53bfb451-f66f-4b6e-b430-8d13c95b30d8\",\"Name\":\"Philip\",\"Surname\":\"MT\"},{\"ID\":\"c7f22b9b-4030-4f82-9f75-bbb726cabb73\",\"Name\":\"Vincent\",\"Surname\":\"Van Der Walt\"},{\"ID\":\"232577be-3165-4316-a20d-c2f2a09c5382\",\"Name\":\"Scott\",\"Surname\":\"Lynn\"},{\"ID\":\"913508a1-5dca-4504-8caf-c8e3dc386fc0\",\"Name\":\"Dan\",\"Surname\":\"MT\"},{\"ID\":\"36054a07-b14d-4c1c-b35f-e00875dde7e5\",\"Name\":\"Sarah\",\"Surname\":\"MT\"},{\"ID\":\"f14e7d98-e040-4ba9-928f-f2ff48116b0b\",\"Name\":\"Josh\",\"Surname\":\"IrishDude\"}]"}
When I inspect the result in fiddler's JSON View, it shows the following JSON:
当我在 fiddler 的 JSON 视图中检查结果时,它显示以下 JSON:
d=[{"ID":"6b2b8c62-31ce-4df2-982b-054ff5f6be72","Name":"Carol","Surname":"IrishWife"},{"ID":"d254740a-0a0f-4a1e-9e4f-0812227dd5af","Name":"Willie","Surname":"Le Roux"},{"ID":"660bf0dd-436a-4588-a9c0-19fd6fdcee23","Name":"Emmas","Surname":"Mum"},{"ID":"6b9403c5-b728-4e96-bcb1-203e7472eec3","Name":"Owen","Surname":"Lima"},{"ID":"d52c08fb-4418-4600-960f-243ff4443ee6","Name":"Tim","Surname":"Lee"},{"ID":"e2aacf5b-8855-44ce-9338-3d39f8ab3349","Name":"Marcello","Surname":"MT"},{"ID":"578be087-8385-46d6-89de-3db31d352cbc","Name":"Carlyn","Surname":"Homegroup"},{"ID":"4c805825-2bee-447a-8b75-41ead17db33e","Name":"George","Surname":"Homegroup"},{"ID":"ae48804f-5e78-42c8-9ba0-4214c98a5a89","Name":"Isla","Surname":"Le Roux"},{"ID":"f8be2f4f-fedb-4863-8a84-44fddea84ea9","Name":"Peter","Surname":"Anderson"},{"ID":"15e7644d-ec43-44ff-a959-47e00112da6b","Name":"Kitty","Surname":"Corbett"},{"ID":"8fd7fccc-335c-4d5c-93b5-4b00f96a9950","Name":"Natalie","Surname":"Archibald"},{"ID":"09b5aad2-2cf1-488a-962b-4d692b05ddea","Name":"Miku","Surname":"Heally"},{"ID":"affa369e-5af3-4537-a0f4-71422956da41","Name":"Steven","Surname":"Corbett"},{"ID":"65f57da3-4f88-4798-9590-83b4ccecfc44","Name":"Tim","Surname":"Archibald"},{"ID":"53bfb451-f66f-4b6e-b430-8d13c95b30d8","Name":"Philip","Surname":"MT"},{"ID":"c7f22b9b-4030-4f82-9f75-bbb726cabb73","Name":"Vincent","Surname":"Van Der Walt"},{"ID":"232577be-3165-4316-a20d-c2f2a09c5382","Name":"Scott","Surname":"Lynn"},{"ID":"913508a1-5dca-4504-8caf-c8e3dc386fc0","Name":"Dan","Surname":"MT"},{"ID":"36054a07-b14d-4c1c-b35f-e00875dde7e5","Name":"Sarah","Surname":"MT"},{"ID":"f14e7d98-e040-4ba9-928f-f2ff48116b0b","Name":"Josh","Surname":"IrishDude"}]
So fiddler can parse it successfully, but on the client, the jquery ajax error callback function displays the following error:
所以fiddler可以解析成功,但是在客户端,jquery ajax错误回调函数显示如下错误:
Error: No conversion from text to application/json
The wcf method is defined as follows:
wcf 方法定义如下:
[OperationContract]
[WebGet(ResponseFormat=WebMessageFormat.Json)]
public string GetPeople(Guid groupId)
{
using (SchedulerContext context = new SchedulerContext())
{
JavaScriptSerializer ser = new JavaScriptSerializer();
var query = from p in context.People
where p.Group_ID == groupId
select new
{
p.ID,
p.Name,
p.Surname
};
return ser.Serialize(query.ToArray());
}
}
And finally, the calling jquery is:
最后,调用 jquery 是:
$.ajax(
{
type: "GET",
dataType: "application/json",
contentType: "json",
data: { groupId: 'ae09a080-5d7c-4e92-9a87-591574b7c4b8' },
url: "WebAPI.svc/GetPeople",
error: function (jqXHR, textStatus, errorThrown) {
alert("error");
},
success: function (msg) {
alert(msg.d[0].Name);
}
}
);
Thanks in advance!
提前致谢!
UPDATE:Thanks to @user1370958, one step closer to the solution.
更新:感谢@user1370958,离解决方案又近了一步。
When changing the error callback function to the following it successfully returns the result...
将错误回调函数更改为以下内容时,它成功返回结果...
error: function (jqXHR, textStatus, errorThrown) {
var test = $.parseJSON(jqXHR.responseText);
var test2 = $.parseJSON(test.d);
alert(test2[0].Name);
},
Not sure why, but I have to parse the result and then parse the nested objects inside that. I'm assuming if any of my returned types contained complex objects it would also have needed another parse...
不知道为什么,但我必须解析结果,然后解析其中的嵌套对象。我假设如果我的任何返回类型包含复杂对象,它也需要另一个解析......
回答by Karbaman
Here, "application/json"
is not a valid value for the dataType
property.
I changed it to "json"
in my project and the same problem was solved.
在这里,"application/json"
不是dataType
属性的有效值。我"json"
在我的项目中将其更改为,并解决了同样的问题。
Please check details here (comment #7): http://bugs.jquery.com/ticket/8216
请在此处查看详细信息(评论 #7):http: //bugs.jquery.com/ticket/8216
回答by McGarnagle
Try adding the MIME type in your server-side code:
尝试在服务器端代码中添加 MIME 类型:
Response.ContentType = "application/json";
回答by Eric Brenden
With WCF 4.0, you can add an attribute called automaticFormatSelectionEnabled
which allows the service to look at the Accept
header in the HTTP request to determine what format to return. As long as what you are returning is serializable, WCF will handle the correct serialization for you. In your jQuery ajax call, the Accept header is added by including accepts: {json: "application/json"}
.
在WCF 4.0 中,您可以添加一个名为的属性automaticFormatSelectionEnabled
,该属性允许服务查看Accept
HTTP 请求中的标头以确定要返回的格式。只要您返回的内容是可序列化的,WCF 就会为您处理正确的序列化。在您的 jQuery ajax 调用中,Accept 标头通过包含accepts: {json: "application/json"}
.
回答by hofnarwillie
I've found a workaround:
我找到了一个解决方法:
The first problem was the circular reference exception on the entity model. To overcome this I use the following code to Detach my entities from the context and then serialize them to strings. I then serialize them on the client using the code below that.
第一个问题是实体模型上的循环引用异常。为了克服这个问题,我使用以下代码从上下文中分离我的实体,然后将它们序列化为字符串。然后我使用下面的代码在客户端上序列化它们。
Service
服务
[WebGet(ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
public string[] GetPeople(Guid groupId)
{
using (SchedulerContext context = new SchedulerContext())
{
var people = (from p in context.People
where p.Group_ID == groupId
select p).ToList();
JavaScriptSerializer ser = new JavaScriptSerializer();
string[] result = new string[people.Count];
for (int i = 0; i<people.Count; i++)
{
context.Detach(people[i]);
string json = ser.Serialize(people[i]);
result[i] = json;
}
return result;
}
}
Client
客户
$.ajax(
{
type: "GET",
//dataType: "application/json",
//dataType: "text/plain",
contentType: "json",
data: { groupId: 'ae09a080-5d7c-4e92-9a87-591574b7c4b8' },
//data: { groupId: 'test' },
//data: { groupId: '739526F1-7C58-4E3B-97D8-4870948BFE32' },
url: "WebAPI.svc/GetPeople",
error: function (jqXHR, textStatus, errorThrown) {
alert(jqXHR.resultText);
},
success: function (people) {
//the returned param "people" is of type string[], so each string needs parsed
$(people).each(function (index, value) {
var person = $.parseJSON(value);
//now I can use the Person object
});
}
}
);
回答by carlosfigueira
I assume you want to return the value of ser.Serialize(query.ToArray())
to the client (an array). But you're returning it as a string, so WCF will escape that JSON into a string, and what you'll end up is not an array, but a string.
我假设您想将 的值返回ser.Serialize(query.ToArray())
给客户端(一个数组)。但是您将它作为字符串返回,因此 WCF 会将该 JSON 转义为字符串,最终得到的不是数组,而是字符串。
Since you're using anonymous types, which aren't natively supported by WCF, you need to use the JavaScriptSerializer
. So to prevent the double-encoding of the JSON (into the string) you should return the data as a Stream
instead, so that WCF won't touch your data (see sample code below).
由于您使用的是 WCF 本身不支持的匿名类型,因此您需要使用JavaScriptSerializer
. 因此,为了防止 JSON 的双重编码(到字符串中),您应该将数据作为 a 返回Stream
,这样 WCF 就不会触及您的数据(请参阅下面的示例代码)。
One more thing: I see your response has a {"d":...}
wrapper, which suggests that you're using the <enableWebScript/>
/ WebScriptEnablingBehavior
/ WebScriptServiceHostFactory
when defining your service / endpoint. Since you're not using the ASP.NET AJAX library, you don't need that wrapping, so you can use the "simpler" <webHttp/>
/ WebHttpBehavior
/ WebServiceHostFactory
instead, and your response won't be wrapped in that "d" object.
还有一两件事:我看到您的回复有一个{"d":...}
包装,这表明你正在使用<enableWebScript/>
/ WebScriptEnablingBehavior
/WebScriptServiceHostFactory
定义您的服务时/端点。既然你不使用ASP.NET AJAX库中,你不需要那个包裹,这样你就可以用“简单” <webHttp/>
/ WebHttpBehavior
/ WebServiceHostFactory
,而是和你的反应不会被包裹在“d”的对象。
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json)]
public System.IO.Stream GetPeople(Guid groupId)
{
using (SchedulerContext context = new SchedulerContext())
{
JavaScriptSerializer ser = new JavaScriptSerializer();
var query = from p in context.People
where p.Group_ID == groupId
select new
{
p.ID,
p.Name,
p.Surname
};
string json = ser.Serialize(query.ToArray());
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
WebOperationContext.Current.OutgoingResponse.ContentType = "application/json; charset=utf-8";
return ms;
}
}