[英]ASP.NET WebService is Wrapping my JSON response with XML tags
我不確定我所缺少的地方出了問題。
我正在構建ASP.NET 2.0(在.Net 3.5框架上)Web應用程序,並且包括一個Web服務。 請注意,這不是 MVC項目。 我希望公開一個將返回JSON字符串的方法; 格式化以提供給jqGrid jQuery插件。
這是我在服務中實現的初步測試方法:感謝( Phil Haack的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包裝,如何實現以上響應?
在您的代碼中,不要“返回” json。 改用:
Context.Response.Write(ser.Serialize(jsonData));
那你就好了
常規return命令可以通過設置更適當的服務格式來幫助您。 有人會說使用它是更好的形式,然后從客戶端將json格式解包。 我說,就是隨便吐出您想使用的東西!
您可能沒有做的三件事:
可能有一種用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\"]}]}"}
更詳細的解釋在這里
將服務標記為ScriptService時,它將自動處理JSON序列化。 您不應該手動序列化響應。 見這對於更詳細的堆棧溢出條目。
如果請求JSON,並且包含[ScriptService]
屬性,則ASP.NET將自動將響應序列化為JSON。 您看到的XML表明未滿足這兩個先決條件之一。 手動序列化為JSON的建議是錯誤的 ,除非您希望使用其他序列化程序,例如Newtonsoft。
這是啟用了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來請求它並處理響應(我們將簡單地從MyClass.Message消息中彈出一個JS警報):
<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彈出窗口中顯示“ Hi”。
也可以看看:
我最好能做到以下幾點:
[WebMethod]
public static void GetDocuments()
{
HttpContext.Current.Response.ContentType = "application/json";
HttpContext.Current.Response.Write(JsonConvert.SerializeObject(repository.GetDocuments()));
HttpContext.Current.Response.End();
}
正確設置內容類型,並將JSON直接寫入響應,然后結束響應,這樣就不會再發送任何數據來破壞響應了,這一點很重要。 這種體系結構的優點是您可以使用所需的任何序列化器,而不僅限於內置的JSON序列化器。 在這種情況下,我使用了Json.NET 。
我意識到這正在濫用體系結構(我個人不喜歡為應該返回數據的對象使用空返回類型),但這是我發現的唯一真正可靠的方法。
另一方面,由於John Saunders 在此描述的原因,您應該切換到WCF或Web API 。 Web API特別易於使用,並允許客戶端和服務器之間進行內容類型協商。
[WebMethod]
public static void GetDocuments()
{
HttpContext.Current.Response.ContentType = "application/json";
HttpContext.Current.Response.Write(JsonConvert.SerializeObject( ^_^ ));
HttpContext.Current.Response.End();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.