2012-05-04 48 views
18

我正在使用jquery調用ajax wcf方法,該方法將對象列表作爲JSON字符串返回。在fiddler2檢查時,它(在TextView中)的JSON字符串如下所示:jquery ajax調用返回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\"}]"} 

當我檢查結果提琴手的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"}] 

所以提琴手可以解析它成功,但在客戶機上,所述的jquery AJAX錯誤回調函數將顯示以下錯誤:

Error: No conversion from text to application/json 

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

最後,調用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); 
      } 
     } 
); 

謝謝!

更新: 感謝@ user1370958,更接近解決方案。

當改變錯誤回調函數來成功地追蹤它返回結果...

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

不知道爲什麼,但我要解析的結果,然後分析裏面的嵌套對象。我假設,如果我的任何返回類型包含複雜的對象,也必須需要另一種解析...

回答

48

這裏, 「應用/ JSON」 是不是爲數據類型屬性的有效值。 我在項目中將其更改爲「json」,並解決了同樣的問題。

請點擊這裏查看詳情(評論#7):http://bugs.jquery.com/ticket/8216

+0

應用程序/ json用於不在jquery ajax中的http標頭。剛剛確認。 –

3

嘗試在你的服務器端代碼添加MIME類型:

Response.ContentType = "application/json"; 
+0

是的,我有沒有成功,得益於雖然 – hofnarwillie

0

我想,你希望將ser.Serialize(query.ToArray())的值返回給客戶端(數組)。但是你將它作爲一個字符串返回,所以WCF將把這個JSON轉義成一個字符串,並且你最終得到的不是一個數組,而是一個字符串。

由於您使用的不是WCF原生支持的匿名類型,因此您需要使用JavaScriptSerializer。因此,爲了防止對JSON進行雙重編碼(在字符串中),您應該將數據返回爲Stream,以便WCF不會觸及您的數據(請參閱下面的示例代碼)。

一兩件事:我看到您的回覆有{"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; 
     } 

} 
+0

感謝,但沒有運氣。我複製了你的代碼,但現在JavaScript錯誤回調沒有錯誤信息,只是空的字符串,並說錯誤是「錯誤」。此外,不再返回resultText。 – hofnarwillie

+0

嘗試在服務器上啓用跟蹤以查看是否有任何奇怪的事情發生。或者查看實際的網絡響應(使用Fiddler或瀏覽器開發人員工具)以查看是否有任何其他信息。 – carlosfigueira

+0

「[Fiddler] ReadResponse()失敗:服務器沒有爲此請求返回響應。」 – hofnarwillie

1

隨着WCF 4.0,您可以添加一個名爲automaticFormatSelectionEnabled一個屬性,它允許服務來查找在HTTP請求中Accept頭,以確定返回什麼格式。只要你返回的是可序列化的,WCF將爲你處理正確的序列化。在你的jQuery ajax調用中,Accept頭被添加,包括accepts: {json: "application/json"}

+0

我會試試這個,我在哪裏添加automaticFormatSelectionEnabled? – hofnarwillie

+0

答案中的鏈接顯示如何在配置中或以編程方式添加它。 –

+0

我試着添加你說的東西。它成功地調用了服務器,我可以通過WebGET。然後它似乎返回,但提琴手報告:[Fiddler] ReadResponse()失敗:服務器沒有返回此請求的響應。錯誤回調再次運行,沒有返回的數據。 – hofnarwillie

0

我已經找到了解決辦法:

的第一個問題是關於實體模型的循環引用除外。爲了解決這個問題,我使用下面的代碼從上下文中分離我的實體,然後將它們序列化爲字符串。然後我使用下面的代碼在客戶端序列化它們。

服務

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

客戶

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

        } 
       } 

     );