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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 09:21:54  来源:igfitidea点击:

jquery ajax call return JSON parsing error

jqueryajaxjsonwcfparsing

提问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 dataTypeproperty. 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 automaticFormatSelectionEnabledwhich allows the service to look at the Acceptheader 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,该属性允许服务查看AcceptHTTP 请求中的标头以确定要返回的格式。只要您返回的内容是可序列化的,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 Streaminstead, 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/ WebScriptServiceHostFactorywhen 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/ WebServiceHostFactoryinstead, 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;
        }

}