使用Javascript 调用.NET WEB服务

Sunday, April 22, 2007

过去使用Javascript调用服务器端代码时,后台代码一直都是放在普通的ASPX页面的Page_Load方法内,一直觉得这种方式不是很好,每实现一个功能都要一个新的页面来实现,也许还有其他问题。如果能够使用WEB服务的话,就可以解决上述问题,如可以在一个Web服务页面内放置多个函数和代码,解决web服务调用验证等。

在网上搜索Javascript调用web服务的方法,找到一篇使用 Ajax 调用 SOAP Web 服务,但总是感觉好像太复杂了,要使用到它的Web Services JavaScript Library。另外一种我知道的方法就是使用ASP.NET Ajax,使用这个库调用web服务很简单并且实现的功能也很强。但是如果不使用这么重量的库能不能直接使用Javascript调用WEB服务呢?

一个偶然的机会,我发现使用ASP.NET编写的Web服务格式是这样的。加入名为Demo的asmx页面中有一个Web方法为foo()。那么调用它的时候,在地址栏显示的地址是Demo.asmx/foo。那么在Javascript能不能直接post(get)到服务器的这个页面呢?答案是可以,从而这样很简单的就实现了通过Javascript 调用WEB服务,也不需要其他库的支持。

下面用一个例子简单实现Javascript 调用WEB服务,假设WEB应用程序的Services/Demo.asmx中存在foo方法返回"Hello World"。

   1: [WebMethod]
   2: public string foo()
   3: {
   4:     return "Hello World";
   5: }

直接通过Services/Demo.asmx/foo访问,得到下面结果,是一个XML文件

   1: <?xml version="1.0" encoding="utf-8" ?> 
   2: <string xmlns="http://sacranto.blogspot.com/">Hello World</string> 

在Javascript中的调用如下:(Javascript中使用了jQuery库,这个库与是否调用WEB服务没有关系,下同)

   1: $(document).ready(function() {
   2:     $("#btnFoo").click(function(){
   3:         $.post("Services/Demo.asmx/foo",
   4:             function(res){
   5:                 alert($(res).text());
   6:             }
   7:         );
   8:     });
   9: });

这段代码用于显示返回xml中的字符,IE7和FF2的结果不同,个人认为FF2的好一些。不知道IE6和其他浏览器的结果怎么样?

12

那么能不能直接传递参数给WEB服务呢?在ASP.NET WEB服务中,答案仍然是可以(使用其他语言编写的WEB服务应该也可以吧)。借助于WebService.Context 获取当前请求的ASP.NET HttpContext,它封装了由 HTTP 服务器用来处理Web 请求的所有HTTP 特定的上下文。

修改请求的Javascript代码,多了传递参数的一行。

   1: $(document).ready(function() {
   2:     $("#btnFoo").click(function(){
   3:         $.post("Services/Demo.asmx/foo",
   4:             {name:'sacranto',age:'24'},
   5:             function(res){
   6:                 alert($(res).text());
   7:             }
   8:         );
   9:     });
  10: });

这样在web服务页面中,可以通过如下代码访问传递的参数

   1: string name = Context.Request.Form["name"];
   2: int age = Convert.ToInt32(Context.Request.Form["age"]);

解决了传递参数的问题,救下来就是返回值了。web服务直接返回的都是xml,我们也可以利用Respone返回其他格式,如text/plain。例如线面的fooText方法就返回了纯文本,记得把方法改成无返回值。

   1: [WebMethod]
   2: public void fooText()
   3: {
   4:     string name = Context.Request.Form["name"];
   5:     int age = Convert.ToInt32(Context.Request.Form["age"]);
   6:     Context.Response.Expires = -1;       
   7:     Context.Response.ContentType = "text/plain";
   8:     Context.Response.Write("Hello " + name + ", your age is " + age.ToString());
   9:     Context.Response.End();
  10: }

在Javascript中的调用与上面基本相同,只是回调类型是text,直接使用即可。这也意味着text可以直接是json字符串了。

   1: $("#btnFooText").click(function(){
   2:     $.post("Services/Demo.asmx/fooText",
   3:         {name:'sacranto',age:'24'},
   4:         function(res){
   5:             alert(res);
   6:         }
   7:     );
   8: });

看看结果

3

使用Javascript 调用.NET WEB服务,是不是很简单呢?

 

 

PS:据说这种方法使用 http://localhost/... 访问就正常, 但用域名会出错。 我试了用IP是没有问题的,用域名?我还没有域名呢 :-)

解决方法:
在Web.config里面加上就可以了.

   1: <webServices> 
   2:     <protocols> 
   3:         <add name="HttpPost" /> 
   4:         <add name="HttpGet" /> 
   5:     </protocols> 
   6: </webServices> 

3 COMMENTS:

Unknown said...

我觉得你的 界面能不能换一下,就是文档不要直接显示,只显示标题.这样大家可以看到自己感兴趣的东西,而不是一打开就是一大段文字?

sacranto said...

多谢
但是好像没有找到这个功能

sacranto said...

找了一个摘要输出的hack
这样首页仿佛是要好一点了