首先说一下,这个问题和AJAX难以分开.其实现方法和AJAX非常类似.有AJAX经验的朋友就很容易理解.
我这里举例的项目没有直接使用MS的AJAX框架而是只引用了该框架中的一个关键DLL和两段脚本.下边我会清楚的说明JS访问WEB SERVICES的具体流程.
首先:准备一个SERVICE,在SERVICE中要加上下边两个引用.
using System.Web.Script.Services;
using System.Web.Script.Serialization;
这两个引用自System.Web.Extensions.dll
没有的话去MS下载, 在MS的AJAX包中就包含
SERVICE.CS代码中
[ScriptService]
public class ElmService : System.Web.Services.WebService
{
[WebMethod(EnableSession = true)]
public string GetElm(string inComType, string inActElmID, string inEftElmsID, string inParamList)
{
…………
}
}
//注意[ScriptService]这个标记 /JS请求就是靠这个标记才输出脚本 脚本内容是对服务的类和方法以及返回结构的封装
第二:在页面上加上三个脚本
脚本A:<script src='script/AJAXSERVICE.js' type='text/javascript'></script>//这个脚本是MS对.NET基本类型和方法的JS版封装,我自己提取出来的,如果页面使用了MS.AJAX框架那么这个JS就已经存在了,不用手动添加了,下边有专门解释。
脚本B:<script src='ElmService.asmx/js' type='text/javascript'></script>//这个是SERVICE自动生成的,[ScriptService]的功劳。
脚本C:<script src='scritp/myservice.js' type='text/javascript'></script>//这个是自己写的脚本,具体的使用服务返回结果的代码。根据业务需要自己写。
在B中,已经有了一个JS对象ElmService和JS方法ElmService.GetElm( inComType, inActElmID, inEftElmsID, ceparamlist, CE_ShowResult, CE_ShowError);
我们看到这个JS方法中的参数和SERVICE代码中的参数基本一样,但是多了两个。这两个其实是方法名。这两个方法是需要我们在脚本C中手写的。分别处理调用服务后正常的返回结果,或者处理调用失败、超时、异常等情况。
脚本C中我们写了这两个方法。
function CE_ShowError( inError) //处理调用SERVICE超时或者处理错误结果
{
alert("服务请求出现错误,也许是因为您的网络出现问题。/r/n您可以稍后再试一次,或者检查您的网络。/r/n The Request has some error, may be your network has some problem. /r/n You can try it later, or cheak your network.");
alert("ErrorMessage:"+inError.get_message());
CE_ShowResultDo();
}
function CE_ShowResult( inServiceResult)// 处理SERVICE返回的正常结果.
{
var tmpstrkk=inServiceResult.replace("<?xml version=/"1.0/" encoding=/"utf-8/" ?>","").replace("<string xmlns=/"http://tempuri.org//">" ,"").replace("</string>" ,"");
var ce_ResultBodyArray=CE_GetResultArray(tmpstrkk);
for (p=0;p<CE_EftElmsIDandHTML.length;p++)
{
for (q=0;q<ce_ResultBodyArray.length;q++)
{
var tmpidkk=CE_EftElmsIDandHTML[p].ElmID;
var tmpidkkk=ce_ResultBodyArray[q].ElmID;
if (tmpidkk.toUpperCase()==tmpidkkk.toUpperCase())
{
CE_EftElmsIDandHTML[p].ElmHTML=ce_ResultBodyArray[q].ElmHTML;
}
}
}
CE_ShowResultDo();
}
第三:我们自己的事件触发SERVICE调用
比如我们有个按扭,ONCLICK="DoService();"
我们脚本C中当然要有DoService()方法
function DoService()
{
var inComType="Com1"; var inActElmID="Elm1"; inEftElmsID="Elm1,Elm2"; ceparamlist="abc=1,bcd=3";
ElmService.GetElm( inComType, inActElmID, inEftElmsID, ceparamlist, CE_ShowResult, CE_ShowError);
}
大家看到了,这里调用GETELM方法是没有返回结果的。SERVICE的返回结果是通过"成功方法" CE_ShowResult来返回的。
根据我们以前的定义function CE_ShowResult( inServiceResult)
inServiceResult就是返回结果了。当SERVICE的返回类型很简单,数字、字符串等返回类型的时候,我们可以直接JS中使用,因为JS是弱类型嘛。可如果返回的是复杂类型数据呢? 现在该我们的脚本A大显身手了。
先说下脚本B,脚本B中不仅仅是SERVICE的类型,还包括返回值类型的封装。但是我们知道在SERVICE中.NET类型和JS中的类型有很大差距的。所以脚本B也要用基本类型来构建我们的结果类型。它是根据什么基本类型实现呢?就是脚本A的内容。脚本A中把.NET的基本数据类型用JS封装了一遍(MS就是牛B)。
比如脚本A中的 int类型就包括了比JS中数字类型更丰的方法,而且命名规则和.NET环境中一样。DateTime类型也提供了与.NET环境中一样的方法,比如 DateTime.ToShotTimeString()方法。 这样我们使用和处理SERVICE返回的复杂数据类型就可以很方便的使用了。
如SERVICE.CS中返回的数据类型是
public class aabb
{
public string name;
public DateTime SiTime;
public int count;
}
那么我们在JS脚本 function CE_ShowResult( inServiceResult) 中就可以写这样的代码:
var res=inServiceResult.name+"_"+inServiceResult.count.ToString()+"_"+inServiceResult.SiTime.ToLongDateString();
顺便说一下在失败处理函数中 inError.get_message() 这也是在脚本B中封装的。
更多的具体高级处理方法和事件,大家可以仔细研究下脚本B和脚本A
脚本A是通过MS的AJAX框架导出的。它本身封在DLL内。
大家可以自己MS.AJAX作一个简单站点,然后查看页面显示出来的代码,把这个JS导出来。稍后我也会把这个文件传到CSDN上来。
第四:
希望大家早日能作出一个全站SERVICE加JS的新型站点。这样的站点比AJAX要快,而且服务压力会小的多的多。
……
本来还有个问题想说明一下,现在脑子不好使想不起来了。我想起来后会在后边跟上。先写到这。