2010-01-13 33 views
11

我不知道我錯在哪裏,我錯過了什麼。ASP.NET WebService正在用XML標記包裝我的JSON響應

我正在構建一個ASP.NET 2.0(在.Net 3.5框架)Web應用程序,我包括一個web服務。請注意,這是而不是的MVC項目。我希望公開一個將返回一個JSON字符串的方法;格式化爲jqGrid jQuery插件。

這是初步的測試方法,我在我的服務中實現:由於(Phil Haack's Guide for MVC

[WebMethod] 
[ScriptMethod(ResponseFormat = ResponseFormat.Json)] 
public string getData() 
{ 
    JavaScriptSerializer ser = new JavaScriptSerializer(); 

    var jsonData = new 
    { 
     total = 1, // we'll implement later 
     page = 1, 
     records = 3, // implement later 
     rows = new[]{ 
      new {id = 1, cell = new[] {"1", "-7", "Is this a good question?", "yay"}}, 
      new {id = 2, cell = new[] {"2", "15", "Is this a blatant ripoff?", "yay"}}, 
      new {id = 3, cell = new[] {"3", "23", "Why is the sky blue?", "yay"}} 
     } 
    }; 

    return ser.Serialize(jsonData); //products.ToString(); 
} 

當調用此函數返回(格式爲清楚起見):

<?xml version="1.0" encoding="utf-8" ?> 
<string mlns="http://tempuri.org/"> 
{ 
    "total":1, 
    "page":1, 
    "records":3, 
    "rows": 
    [ 
     {"id":1,"cell":["1","-7","Is this a good question?","yay"]}, 
     {"id":2,"cell":["2","15","Is this a blatant ripoff?","yay"]}, 
     {"id":3,"cell":["3","23","Why is the sky blue?","yay"]} 
    ] 
} 
</string> 

會如何我實現了上述迴應沒有的xml包裝?

回答

8

三樣東西你可能不會做:

  • 標記靜態
  • 進行後
  • 手空「{}」爲jQuery中的數據的方法。

可能有一種方法用GET調用方法,我只用過POST。我能得到你的例子有這方面的工作:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> 
<script> 
    // In your javascript block 
    $(document).ready(function() 
    { 
     $.ajax({ 
      url: "/Default.aspx/Tester", 
      type: "POST", 
      contentType: "application/json; charset=utf-8", 
      dataType: "json", 
      data: "{}", 
      success: done 
     }); 
    }); 

    function done(data) 
    { 
     // Include http://www.json.org/json2.js if your browser doesn't support JSON natively 
     var data = JSON.parse(data.d); 
     alert(data.total); 
    } 
</script> 

背後的代碼(你不需要創建Web服務,你可以把這個在你的Default.aspx):

[WebMethod] 
public static string Tester() 
{ 
    JavaScriptSerializer ser = new JavaScriptSerializer(); 

    var jsonData = new 
    { 
     total = 1, // we'll implement later 
     page = 1, 
     records = 3, // implement later 
     rows = new[]{ 
       new {id = 1, cell = new[] {"1", "-7", "Is this a good question?", "yay"}}, 
       new {id = 2, cell = new[] {"2", "15", "Is this a blatant ripoff?", "yay"}}, 
       new {id = 3, cell = new[] {"3", "23", "Why is the sky blue?", "yay"}} 
      } 
     }; 

    return ser.Serialize(jsonData); //products.ToString(); 
} 

其結果是:

{"d":"{\"total\":1,\"page\":1,\"records\":3,\"rows\":[{\"id\":1,\"cell\":[\"1\",\"-7\",\"Is this a good question?\",\"yay\"]},{\"id\":2,\"cell\":[\"2\",\"15\",\"Is this a blatant ripoff?\",\"yay\"]},{\"id\":3,\"cell\":[\"3\",\"23\",\"Why is the sky blue?\",\"yay\"]}]}"} 

更詳細的解釋是here

+0

你是如何得到結果的。當我像你一樣執行時,我似乎只返回「[object Object]」。這可能是JSON天真,但我似乎無法得到它的工作。 – Mike 2010-01-14 09:35:10

+0

我在Firefox中使用firebug查看網絡面板的響應 - 單擊該請求的響應選項卡。 – 2010-01-14 09:59:40

+0

你知道爲什麼數據被包裹在變量「d」中嗎? – Mike 2010-01-14 10:07:08

9

在你的代碼中,不要「返回」json。改用:

Context.Response.Write(ser.Serialize(jsonData));

然後你會好。

定期回覆命令幫助您通過放入更合適的服務格式。有人會說這是更好的形式來使用它,並從這種格式解開你的客戶端的JSON。我說,只是吐下你想要使用它的東西!

+1

這似乎工作,如果您導航到.aspx頁面,然後按照通過鏈接調用。不幸的是,如果我嘗試導航到「GridDataRequest.asmx/getData」,我會遇到一個死亡的黃色屏幕「請求格式無法識別,因爲URL意外地以'/ getData'結尾。」 – Mike 2010-01-14 09:17:01

+1

+1這個方便的寶石代碼。然而,我選擇了另一種解決方案來更好地適應我們的模型。 – Mike 2010-01-14 14:28:33

+0

是的,只要你使用jquery,最好使用json.parse。更合適。 – 2010-01-14 15:45:58

2

當您將服務標記爲ScriptService時,它會自動處理JSON序列化。您不應該手動序列化響應。 有關更多詳細信息,請參見this堆棧溢出條目。

+0

正確。除非你想使用不同的序列化程序,比如Newtonsoft,它可以讓asmx按照設計工作 - 包括爲你處理序列化。在響應中沒有獲取XML的關鍵是確保IIS知道需要JSON。然後,只需返回C#對象並將序列化自動發生爲JSON:http://stackoverflow.com/a/16335022/397817 – 2013-10-08 08:43:01

1

如果REQ如果包含[ScriptService]屬性,則ASP.NET會自動將響應序列化爲JSON。你看到XML表明這兩個前提條件之一沒有得到滿足。 除非您希望使用不同的序列化程序,例如Newtonsoft,否則手動將序列化爲JSON的建議是錯誤的

這裏是一個JSON的一個簡單的工作示例啓用ASMX Web服務:

<%@ WebService Language="C#" Class="WebService" %> 
using System; 
using System.Collections.Generic; 
using System.Web.Services; 

[WebService(Namespace = "http://tempuri.org/")] 
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 
[System.Web.Script.Services.ScriptService] 
public class WebService : System.Web.Services.WebService { 
    [WebMethod] 
    public MyClass Example() 
    { 
     return new MyClass(); 
    } 

    public class MyClass 
    { 
     public string Message { get { return "Hi"; } } 
     public int Number { get { return 123; } } 
     public List<string> List { get { return new List<string> { "Item1", "Item2", "Item3" }; } } 
    } 
} 

JavaScript來要求它,並處理響應(我們將簡單地彈出一個JS警報從MyClass.Message消息):

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
    <title>Test</title> 
    <script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.4.js" type="text/javascript"></script> 
</head> 
<body> 
    <script type="text/javascript"> 
     $.ajax({ 
      type: "POST", 
      url: "WebService.asmx/Example", 
      contentType: "application/json; charset=utf-8", 
      dataType: "json", 
      data: "{ }", 
      error: function (XMLHttpRequest, textStatus, errorThrown) { alert(langError + " " + textStatus); }, 
      success: function (msg) { 
       alert(msg.d.Message); 
      } 
     }); 
    </script> 
</body> 
</html> 

HTTP請求:

POST http://HOST.com/WebService.asmx/Example HTTP/1.1 
Accept: application/json, text/javascript, */*; q=0.01 
Content-Type: application/json; charset=utf-8 
X-Requested-With: XMLHttpRequest 
Referer: http://HOST.com/Test.aspx 
Accept-Language: en-GB,en;q=0.5 
Accept-Encoding: gzip, deflate 
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0) 
Connection: Keep-Alive 
Content-Length: 3 
Host: HOST.com 

{ } 

HTTP響應:

HTTP/1.1 200 OK 
Cache-Control: private, max-age=0 
Content-Type: application/json; charset=utf-8 
Server: Microsoft-IIS/8.0 
X-AspNet-Version: 4.0.30319 
X-Powered-By: ASP.NET 
Date: Tue, 08 Oct 2013 08:36:12 GMT 
Content-Length: 98 

{"d":{"__type":"WebService+MyClass","Message":"Hi","Number":123,"List":["Item1","Item2","Item3"]}} 

結果:

「嗨」 顯示在一個JS彈出。

參見:

https://stackoverflow.com/a/16335022/397817

https://stackoverflow.com/a/3839649/397817

1

我有更好的運氣與執行以下操作:

[WebMethod] 
public static void GetDocuments() 
{ 
    HttpContext.Current.Response.ContentType = "application/json"; 
    HttpContext.Current.Response.Write(JsonConvert.SerializeObject(repository.GetDocuments())); 
    HttpContext.Current.Response.End(); 
} 

設置內容鍵入正確是很重要的,並將JSON直接寫入響應,然後結束響應,以便不會發送更多數據來破壞響應SE。這種體系結構的一個優點是你可以使用你想要的任何序列化器,你並不侷限於內置的JSON序列化器。在這種情況下,我使用了Json.NET。我認識到這是濫用架構(我個人不喜歡有一個返回類型的東西,應該返回數據),但這是我發現的唯一真正可靠的方法。

另一方面,您應該切換到WCF或Web API,原因是John Saunders描述了here。特別是Web API非常易於使用,並且允許在客戶端和服務器之間進行內容類型協商。