ASP.NET WebService is Wrapping my JSON response with XML tags

前端 未结 6 1095
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-03 11:49

I\'m not sure where I\'m going wrong of what I\'m missing.

I\'m building an ASP.NET 2.0 (on the .Net 3.5 framework) Web application and I am including a webservice.

相关标签:
6条回答
  • 2020-12-03 12:00

    If you request JSON, and if you include the [ScriptService] attribute, ASP.NET will automatically serialise the response to JSON. That you were seeing XML suggests one of these 2 preconditions were not being met. The suggestions to serialise to JSON manually are wrong, unless you wish to use a different serialiser such as Newtonsoft.

    Here is a simple working example of a JSON enabled ASMX web service:

    <%@ 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 to request it and process the response (we'll simply pop up a JS alert with the message from 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 request:

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

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

    Result:

    "Hi" is displayed in a JS popup.

    See also:

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

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

    0 讨论(0)
  • 2020-12-03 12:02

    In your code, don't "return" the json. Use instead:

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

    Then you'll be good.

    The regular return command helps you by putting in a more proper service format. Some would say it'd be better form to use this, and unwrap your json on the client from this format. I say, just spit down the stuff exactly how you want to use it!

    0 讨论(0)
  • 2020-12-03 12:05

    When you mark the service as a ScriptService, it automatically handles the JSON serialization. You shouldn't manually serialize the response. See this stack overflow entry for more detail.

    0 讨论(0)
  • 2020-12-03 12:10
    1. turn the return type to void
    2. put your object onto ^_^
    [WebMethod]
    public static void GetDocuments()
    {
        HttpContext.Current.Response.ContentType = "application/json";
        HttpContext.Current.Response.Write(JsonConvert.SerializeObject( ^_^ ));
        HttpContext.Current.Response.End();
    }
    
    0 讨论(0)
  • 2020-12-03 12:12

    Three things you may not be doing:

    • Marking the method static
    • Performing a POST
    • Hand an empty "{ }" for the data in jQuery.

    There may be a way to call the method with a GET, I've only ever used POST. I was able to get your example working with this:

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

    The code behind (you don't need to create a webservice, you can put this in your 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();
    }
    

    The result:

    {"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\"]}]}"}
    

    A more detailed explanation is here

    0 讨论(0)
  • 2020-12-03 12:23

    I've had better luck with doing the following:

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

    It's important to set the content type properly, and to write the JSON directly to the respond, then to end the response so that no further data is sent to corrupt your response. An advantage of this architecture is you can use whatever serializer you want, you're not limited to the built in JSON serializer. In this case, I used Json.NET.

    I realize that this is abusing the architecture (and I personally dislike having a void return type for something that's supposed to return data) but this is the only truly reliable method I've found.

    On the other hand, you should be switching to WCF or Web API, for reasons John Saunders describes here. Web API in particular is very easy to use, and allows for content type negotiation between the client and server.

    0 讨论(0)
提交回复
热议问题