jquery ajax call return JSON parsing error

前端 未结 5 1281
走了就别回头了
走了就别回头了 2020-12-30 23:14

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):

相关标签:
5条回答
  • 2020-12-30 23:55

    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
                            });
    
                        }
                    }
    
            );
    
    0 讨论(0)
  • 2020-12-30 23:59

    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.

    Please check details here (comment #7): http://bugs.jquery.com/ticket/8216

    0 讨论(0)
  • 2020-12-31 00:10

    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.

    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).

    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.

    [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;
            }
    
    }
    
    0 讨论(0)
  • 2020-12-31 00:12

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

    0 讨论(0)
  • 2020-12-31 00:14

    Try adding the MIME type in your server-side code:

    Response.ContentType = "application/json";
    
    0 讨论(0)
提交回复
热议问题