C# ASP.NET WebService正在用XML标记包装我的JSON响应
我不知道我错在哪里,也不知道我错过了什么 我正在构建一个ASP.NET2.0(在.NET3.5框架上)Web应用程序,并包含一个Web服务。请注意,这不是一个MVC项目。我希望公开一个返回JSON字符串的方法;格式化为提供jqGrid jQuery插件 这是我在服务中实现的初步测试方法:感谢() 调用时,返回(格式清晰):C# ASP.NET WebService正在用XML标记包装我的JSON响应,c#,asp.net,json,web-services,javascriptserializer,C#,Asp.net,Json,Web Services,Javascriptserializer,我不知道我错在哪里,也不知道我错过了什么 我正在构建一个ASP.NET2.0(在.NET3.5框架上)Web应用程序,并包含一个Web服务。请注意,这不是一个MVC项目。我希望公开一个返回JSON字符串的方法;格式化为提供jqGrid jQuery插件 这是我在服务中实现的初步测试方法:感谢() 调用时,返回(格式清晰): { “总数”:1, “页码”:1, “记录”:3, “行”: [ {“id”:1,“cell”:[“1”,“-7”,“这是个好问题吗?”,“耶”]}, {“id”:2,“c
{
“总数”:1,
“页码”:1,
“记录”:3,
“行”:
[
{“id”:1,“cell”:[“1”,“-7”,“这是个好问题吗?”,“耶”]},
{“id”:2,“cell”:[“2”,“15”,“这是明目张胆的剽窃吗?”,“耶”],
{“id”:3,“cell”:[“3”,“23”,“为什么天空是蓝色的?”,“耶”]}
]
}
如果没有xml包装,我将如何实现上述响应?在代码中,不要“返回”json。改用:
Context.Response.Write(ser.Serialize(jsonData))代码>
那你就好了
常规return命令通过使用更合适的服务格式来帮助您。有人会说,最好使用这种格式,并从这种格式在客户机上展开json。我说,把你想用的东西吐出来 将服务标记为ScriptService时,它会自动处理JSON序列化。您不应该手动序列化响应。
有关更多详细信息,请参阅堆栈溢出条目。您可能没有做的三件事:
- 将方法标记为静态
- 执行职务
- 为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>
结果是:
{"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,并且如果您包含[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" }; } }
}
}
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弹出窗口中
另见:
我在做以下事情时运气更好:
[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序列化程序。在这种情况下,我使用了
我意识到这是在滥用体系结构(我个人不喜欢对应该返回数据的东西使用void返回类型),但这是我发现的唯一真正可靠的方法
另一方面,您应该切换到WCF,或者,出于John Saunders描述的原因。Web API尤其易于使用,并允许客户机和服务器之间进行内容类型协商
将返回类型改为void
把你的物体放到^ u^
如果您导航到.aspx页面,然后按照链接进行调用,这似乎是可行的。不幸的是,如果我尝试导航到“GridDataRequest.asmx/getData”,则无法识别意外以“/getData.”结尾的URL的请求格式“+1”这一方便的代码。不过,我选择了另一个更适合我们模型的解决方案。是的,最好使用json.parse,只要您仍然使用jquery。更合适。你是怎么得到结果的。当我像您一样实现时,我似乎只得到了“[object]”。这对JSON来说可能很幼稚,但我似乎无法让它工作。我使用Firefox中的firebug查看来自网络面板的响应-单击该请求的响应选项卡。你知道为什么数据被包装在变量“d”中吗?jQuery没有添加“d”,而是添加了.Net 3.5作为安全措施。正确。除非您想使用不同的序列化程序,如Newtonsoft,否则最好让asmx按设计工作,这包括为您处理序列化。不在响应中获取XML的关键是确保IIS知道需要JSON。然后只需返回C#对象,JSON的序列化就会自动进行:
<%@ 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" }; } }
}
}
<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>
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/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"]}}
[WebMethod]
public static void GetDocuments()
{
HttpContext.Current.Response.ContentType = "application/json";
HttpContext.Current.Response.Write(JsonConvert.SerializeObject(repository.GetDocuments()));
HttpContext.Current.Response.End();
}
[WebMethod]
public static void GetDocuments()
{
HttpContext.Current.Response.ContentType = "application/json";
HttpContext.Current.Response.Write(JsonConvert.SerializeObject( ^_^ ));
HttpContext.Current.Response.End();
}