簡體   English   中英

ASP.NET WebService正在用XML標簽包裝我的JSON響應

[英]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格式解包。 我說,就是隨便吐出您想使用的東西!

您可能沒有做的三件事:

  • 將方法標記為靜態
  • 執行POST
  • 為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\"]}]}"}

更詳細的解釋在這里

將服務標記為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”。

也可以看看:

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

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

我最好能做到以下幾點:

[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特別易於使用,並允許客戶端和服務器之間進行內容類型協商。

  1. 將返回類型設置為void
  2. 將您的對象放在^ _ ^上
[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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM