C# ASP.NET WebService 正在用 XML 标记包装我的 JSON 响应

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2058454/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 23:07:36  来源:igfitidea点击:

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

c#asp.netjsonweb-servicesjavascriptserializer

提问by Mike

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. Note that this is notan MVC project. I wish to expose a method which will return a JSON string; formatted to feed the jqGrid jQuery plugin.

我正在构建一个 ASP.NET 2.0(在 .Net 3.5 框架上)Web 应用程序,我正在包括一个 web 服务。请注意,这不是一个 MVC 项目。我希望公开一个返回 JSON 字符串的方法;格式化以提供 jqGrid jQuery 插件。

This is the preliminary test method I've implemented in my service: thanks to (Phil Haack's Guide for MVC)

这是我在我的服务中实现的初步测试方法:感谢(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();
}

When invoked this is returning (formatted for clarity):

调用时返回(格式清晰):

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

How would I achieve the above response withoutthe xml wrappings?

如果没有xml 包装,我将如何实现上述响应?

采纳答案by Chris S

Three things you may not be doing:

你可能不会做的三件事:

  • Marking the method static
  • Performing a POST
  • Hand an empty "{ }" for the data in jQuery.
  • 将方法标记为静态
  • 执行 POST
  • 为 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:

可能有一种方法可以使用 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>

The code behind (you don't need to create a webservice, you can put this in your default.aspx):

后面的代码(你不需要创建一个webservice,你可以把它放在你的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

更详细的解释在这里

回答by Patrick Karcher

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

在您的代码中,不要“返回”json。改用:

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

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

Then you'll be good.

那你就好了。

The regular return command helpsyou 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!

常规返回命令通过放入更合适的服务格式来帮助您。有人会说使用它会更好,并从这种格式在客户端上解开你的json。我说,只是吐出你想如何使用它的东西!

回答by Anthony

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

当您将服务标记为 ScriptService 时,它​​会自动处理 JSON 序列化。您不应该手动序列化响应。有关更多详细信息,请参阅堆栈溢出条目。

回答by Stephen Kennedy

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.

如果您请求 JSON,并且包含该[ScriptService]属性,则 ASP.NET 将自动将响应序列化为 JSON。您看到的 XML 表明未满足这两个先决条件之一。手动序列化为JSON 的建议是错误的,除非您希望使用不同的序列化程序,例如 Newtonsoft。

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

这是启用 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 to request it and process the response (we'll simply pop up a JS alert with the message from MyClass.Message) :

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

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

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

Result:

结果:

"Hi" is displayed in a JS popup.

“嗨”显示在 JS 弹出窗口中。

See also:

也可以看看:

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

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

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

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

回答by mason

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.

正确设置内容类型,将 JSON 直接写入响应,然后结束响应,这样就不会发送更多数据来破坏响应,这一点很重要。这种架构的一个优点是你可以使用任何你想要的序列化器,你不限于内置的 JSON 序列化器。在这种情况下,我使用了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.

我意识到这是在滥用架构(我个人不喜欢为应该返回数据的东西使用 void 返回类型)但这是我发现的唯一真正可靠的方法。

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.

另一方面,您应该切换到 WCF 或Web API,原因是 John Saunders在这里描述的。特别是 Web API 非常易于使用,并且允许客户端和服务器之间的内容类型协商。

回答by spoke mind

  1. turn the return type to void
  2. put your object onto ^_^
  1. 将返回类型转为 void
  2. 把你的对象放到 ^_^
[WebMethod]
public static void GetDocuments()
{
    HttpContext.Current.Response.ContentType = "application/json";
    HttpContext.Current.Response.Write(JsonConvert.SerializeObject( ^_^ ));
    HttpContext.Current.Response.End();
}