ASP.NET WebService使用XML标记包装我的JSON响应

我不确定我错过了什么,我错过了什么。

我正在构建一个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(); } 

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

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

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

你可能不会做的三件事:

  • 将方法标记为静态
  • 执行POST
  • 为jQuery中的数据提供一个空的“{}”。

可能有一种方法用GET调用该方法,我只使用过POST。 我能够让你的例子使用这个:

   

后面的代码(您不需要创建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\"]}]}"} 

这里有更详细的解释

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

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

那你就会好起来的。

常规返回命令可以通过提供更合适的服务格式来帮助您。 有些人会说使用它是更好的forms,并从这种格式打开客户端上的json。 我说,只是吐出你想要使用它的东西!

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

做以下事情我有更好的运气:

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

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

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

如果您请求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 List { get { return new List { "Item1", "Item2", "Item3" }; } } } } 

JavaScript请求它并处理响应(我们只需使用来自MyClass.Message的消息弹出JS警报):

   Test       

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

结果:

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

也可以看看:

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

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