Showing posts with label Javascript. Show all posts
Showing posts with label Javascript. Show all posts

使用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> 

......

[阅读全文]

Javascript 的命名空间、类、属性和方法

Saturday, April 21, 2007

今天在网上看了一些实现Javascript 的命名空间、类、属性和方法的文章,下面是我自己尝试的代码,由于对Javascript这种prototype型的语言的理解不是很深,理解可能有误,还好实现应该没有问题的:-)

一. 命名空间:分为两个部分。第一个部分是注册函数,另外一部分是声明命名空间

命名空间注册函数,参照yui的方式,注意这种方式下所有的命名空间的第一级都是sacranto。

   1: var sacranto = {};
   2: sacranto.namespace=function(ns){
   3:     if(!ns||!ns.length){
   4:         return null;
   5:     }
   6:     
   7:     var levels = ns.split(".");
   8:     var nsobj=sacranto;
   9:     
  10:     for(var i=(levels[0] == "sacranto")?1:0;i<levels.length;i++){
  11:         nsobj[levels[i]]=nsobj[levels[i]]||{};
  12:         nsobj = nsobj[levels[i]];
  13:     }
  14:     
  15:     return nsobj;
  16: };    

声明命名空间的语句,这样我们就注册了一个sacranto.demo命名空间。

   1: sacranto.namespace("demo");

二. 类:对于prototype类型的语言,函数其实就是类,声明一个函数其实就声明了一个类,并且他还是是类的静态构造函数。下面的语句声明了一个类,静态构造函数里面什么也没有做。

   1: sacranto.demo.aclass = function(){};

三. 类的属性和方法:这里就需要使用到prototype这个特性了

   1: sacranto.demo.aclass.prototype = {
   2:     //属性
   3:     version: "1.0",
   4:     //方法
   5:     bar: function(s){
   6:         return "hello " + s;
   7:     }
   8: };

四. 静态方法:仿佛在javascript里面应该没有静态方法这个概念吧。我的理解是这样的

   1: //我理解的静态方法,其实是另外一个类和它的静态构造函数。
   2: sacranto.demo.aclass.foo=function(s){
   3:     return "hello "+s;
   4: }

OK,完成,测试一下吧

   1: window.onload = function(){
   2:     var aobj=new sacranto.demo.aclass();
   3:     alert(aobj.bar("world"));                    //成功
   4:     //alert(sacranto.demo.aclass.bar("world"));    //失败
   5:     alert(sacranto.demo.aclass.foo("world"));    //成功
   6: };

 

延伸阅读:

Private Members in JavaScript 英文:讨论了类中的私有成员

prototype的一个优势也是缺点    中文:prototype实现类的属性和方法,以及在运行时刻会改变的特点。

 

PS:取消 使用IE打开包括JavaScript 的本地web页时收到安全警告 方法

1. 在 工具 菜单上, 单击 Internet选项
2. 单击 高级 选项卡
3. 在 设置 列表, 确定依次选中 安全--允许活动内容在本机上的文件中运行。此选项允许您运行脚本和 ActiveX 控件在 InternetExplorer 中
4. 在 文件 菜单上, 单击 关闭

......

[阅读全文]