jquery Ajax-Aufruf gibt JSON-Parsing-Fehler zurück

Lesezeit: 8 Minuten

Benutzer-Avatar
Hofnarwillie

Ich verwende jquery, um eine Ajax-WCF-Methode aufzurufen, die eine Liste von Objekten als JSON-String zurückgibt. Die JSON-Zeichenfolge sieht folgendermaßen aus, wenn sie in fiddler2 (in TextView) untersucht wird:

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

Wenn ich das Ergebnis in der JSON-Ansicht von Fiddler überprüfe, wird das folgende JSON angezeigt:

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

Fiddler kann es also erfolgreich parsen, aber auf dem Client zeigt die JQuery-Ajax-Fehlerrückruffunktion den folgenden Fehler an:

Error: No conversion from text to application/json

Die wcf-Methode ist wie folgt definiert:

    [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());
        }   
    }

Und schließlich ist die aufrufende 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);
            }
        }
);

Danke im Voraus!

AKTUALISIEREN:
Dank @user1370958 der Lösung einen Schritt näher.

Wenn Sie die Fehler-Callback-Funktion wie folgt ändern, wird das Ergebnis erfolgreich zurückgegeben …

error: function (jqXHR, textStatus, errorThrown) {
    var test = $.parseJSON(jqXHR.responseText);
    var test2 = $.parseJSON(test.d);
    alert(test2[0].Name);
},

Ich bin mir nicht sicher warum, aber ich muss das Ergebnis parsen und dann die darin verschachtelten Objekte parsen. Ich gehe davon aus, dass, wenn einer meiner zurückgegebenen Typen komplexe Objekte enthalten hätte, auch eine weitere Analyse erforderlich gewesen wäre …

Benutzer-Avatar
Petr Lazarev

Hier, "application/json" ist kein gültiger Wert für die dataType Eigentum. Ich habe es geändert "json" in meinem Projekt und das gleiche Problem wurde gelöst.

Bitte überprüfen Sie die Details hier (Kommentar Nr. 7): http://bugs.jquery.com/ticket/8216

  • application/json wird in http-Headern verwendet, nicht in jquery ajax. gerade bestätigt.

    – Leap-Hawk

    7. September 2017 um 15:07 Uhr

Versuchen Sie, den MIME-Typ in Ihren serverseitigen Code einzufügen:

Response.ContentType = "application/json";

Mit WCF 4.0können Sie ein Attribut namens hinzufügen automaticFormatSelectionEnabled die es dem Dienst ermöglicht, sich die anzusehen Accept -Header in der HTTP-Anforderung, um zu bestimmen, welches Format zurückgegeben werden soll. Solange das, was Sie zurückgeben, serialisierbar ist, übernimmt WCF die korrekte Serialisierung für Sie. In Ihrem jQuery-Ajax-Aufruf wird der Accept-Header durch Einschließen hinzugefügt accepts: {json: "application/json"}.

  • Ich werde das versuchen, wo füge ich automaticFormatSelectionEnabled hinzu?

    – Hofnarwillie

    4. Mai 2012 um 21:58 Uhr

  • Der Link in der Antwort zeigt, wie Sie es in der Konfiguration oder programmgesteuert hinzufügen.

    – Anna Brenden

    4. Mai 2012 um 22:06 Uhr


  • Ich habe versucht, das von Ihnen Gesagte hinzuzufügen. Es ruft den Server erfolgreich auf und ich kann das WebGET durchlaufen. Dann scheint es zurückzukehren, aber Geiger berichtet: [Fiddler] ReadResponse() fehlgeschlagen: Der Server hat keine Antwort auf diese Anfrage zurückgegeben. Und der Fehlerrückruf wird erneut ohne zurückgegebene Daten ausgeführt.

    – Hofnarwillie

    4. Mai 2012 um 22:35 Uhr

Ich nehme an, Sie möchten den Wert von zurückgeben ser.Serialize(query.ToArray()) an den Client (ein Array). Aber Sie geben es als Zeichenfolge zurück, sodass WCF diesen JSON-Code in eine Zeichenfolge umwandelt, und Sie erhalten am Ende kein Array, sondern eine Zeichenfolge.

Da Sie anonyme Typen verwenden, die von WCF nicht nativ unterstützt werden, müssen Sie die JavaScriptSerializer. Um also die doppelte Codierung des JSON (in den String) zu verhindern, sollten Sie die Daten als Stream stattdessen, damit WCF Ihre Daten nicht berührt (siehe Beispielcode unten).

Noch etwas: Ich sehe, Ihre Antwort hat a {"d":...} Wrapper, was darauf hindeutet, dass Sie die verwenden <enableWebScript/> / WebScriptEnablingBehavior / WebScriptServiceHostFactory beim Definieren Ihres Dienstes / Endpunkts. Da Sie die ASP.NET AJAX-Bibliothek nicht verwenden, benötigen Sie diese Umhüllung nicht, sodass Sie die “einfachere” verwenden können. <webHttp/> / WebHttpBehavior / WebServiceHostFactory stattdessen, und Ihre Antwort wird nicht in dieses “d”-Objekt eingeschlossen.

[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;
        }

}

Ich habe einen Workaround gefunden:

Das erste Problem war die Zirkelverweisausnahme im Entitätsmodell. Um dies zu überwinden, verwende ich den folgenden Code, um meine Entitäten vom Kontext zu trennen und sie dann in Zeichenfolgen zu serialisieren. Ich serialisiere sie dann auf dem Client mit dem Code darunter.

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;
        }   
    }

Klient

        $.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
                        });

                    }
                }

        );

1176370cookie-checkjquery Ajax-Aufruf gibt JSON-Parsing-Fehler zurück

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy