13

我不确定我错过了什么。

我正在构建一个 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 包装,我将如何实现上述响应?

4

6 回答 6

10

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

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

那你就好了。

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

于 2010-01-13T16:53:57.203 回答
10

您可能不会做的三件事:

  • 将方法标记为静态
  • 执行 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>

后面的代码(你不需要创建一个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();
}

结果:

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

更详细的解释在这里

于 2010-01-13T17:22:31.457 回答
2

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

于 2010-01-13T16:56:54.717 回答
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 直接写入响应非常重要,然后结束响应,这样就不会发送更多数据来破坏您的响应。这种架构的一个优点是你可以使用任何你想要的序列化器,你不限于内置的 JSON 序列化器。在这种情况下,我使用了Json.NET

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

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

于 2014-11-17T15:02:16.313 回答
1

如果您请求 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 弹出窗口中。

也可以看看:

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

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

于 2013-10-08T08:59:22.737 回答
1
  1. 将返回类型变为 void
  2. 把你的对象放到^_^
[WebMethod]
public static void GetDocuments()
{
    HttpContext.Current.Response.ContentType = "application/json";
    HttpContext.Current.Response.Write(JsonConvert.SerializeObject( ^_^ ));
    HttpContext.Current.Response.End();
}
于 2019-05-16T11:48:42.807 回答