Microsoft Asp.Net Ajax框架入门(11) 调用内部Web Services

VS 2008

本文介绍在客户端js中如何调用程序内部的Web Services

1. 创建可供客户端js调用的Web Service
    新建一个Web Service: UserSvc.asmx
    
using System;
using System.Collections;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Script.Services;
using System.Web.Services.Protocols;
using System.Xml.Linq;

/// <summary>
/// Summary description for UserSvc
/// </summary>

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo 
= WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
[ScriptService]
public class UserSvc : System.Web.Services.WebService {

    
public UserSvc () {

        
//Uncomment the following line if using designed components 
        
//InitializeComponent(); 
    }


    [WebMethod]
    
public string GetUserName(int userId) {
        
return userId == 1 ? "guozhijian" : string.Empty;
    }

    
}
    
    1) 添加using System.Web.Script.Services
    2) 为类UserSvc加上[ScriptService]的Attribute
    3) 与普通WebServices一样,方法需要加上[WebMethod]的Attribute

    现在转到客户端,在页面上添加ScriptManager控件
<asp:ScriptManager ID="sMgr" runat="server">
        
<Services>
            
<asp:ServiceReference Path="~/UserSvc.asmx" />
        
</Services>
    
</asp:ScriptManager>
    在页面上置一个input button,点击后调用UserSvc的GetUserName方法
<input type="button" id="btnGetUserName" value="get UserName" onclick="btnGetUserNameClickHandler();" />

<script type="text/javascript">
        function btnGetUserNameClickHandler() 
{
            UserSvc.GetUserName(
1, getUserNameSucceed, getUserNameFailed, {msg: "this is a message"});
        }

        function getUserNameSucceed(result, ctx, methodName) 
{
            alert(result);
            alert(ctx.msg);
            alert(methodName);
        }

        function getUserNameFailed(err, ctx, methodName) 
{
            alert(err.get_message());
            alert(ctx.msg);
            alert(methodName);
        }

    
</script>

    如果使用VS 2008,在客户端将会智能感知出UserSvc及其方法。在UserSvc中定义的GetUserName方法,在客户端调用的时候接受几个参数,首先是在UserSvc中定义的参数列表,然后是Webservice调用成功后回调的方法,调用失败后回调的方法,最后一个是上下文参数。
    本例中,调用web service成功后回调的方法是 getUserNameSucceed, 失败后的回调方法是getUserNameFailed方法,而上下文参数我随便定义了一个{msg : "this is a message"}的对象
    对于回调函数的方法,定义为3个参数,第一个result是web service 方法的返回值,第二个是上下文参数,第三个methodName为本次调用的Webservice中定义的方法名。
    为测试异常发生的情况,将UserSvc中的GetUserName方法略作修改:
[WebMethod]
    
public string GetUserName(int userId) {
        
//return userId == 1 ? "guozhijian" : string.Empty;
        throw new Exception("an error occured");
    }
    
    调用Web Service的时候,可以设置调用超时的时间限制:
function btnGetUserNameClickHandler() {
            UserSvc.set_timeout(
1000);
            UserSvc.GetUserName(
1, getUserNameSucceed, getUserNameFailed, {msg: "this is a message"});
        }
    既是在调用GetUserName方法前调用set_timeout方法,本例意为:1秒超时
    改一下web service端的GetUserName方法:
[WebMethod]
    
public string GetUserName(int userId) {
        System.Threading.Thread.Sleep(
2000);
        
return userId == 1 ? "guozhijian" : string.Empty;
    }
    这样,1秒以后就是调用 getUserNameFailed方法。提示超时错误。    

2. 处理复杂类型
    在服务端新建一个UserInfo类:
public class UserInfo
{
    
public int UserId {
        
get;
        
set;
    }

    
public string UserName {
        
get;
        
set;
    }

}
    在UserSvc中定义一个获取UserInfo的方法:
[WebMethod]
    
public UserInfo GetUserInfo(int userId) {
        
return userId == 1 ? new UserInfo() { UserId = 1, UserName = "guozhijian" } : null;
    }
    在客户端调用该方法,并获得返回的UserInfo:
function btnGetUserNameClickHandler() {
            UserSvc.GetUserInfo(
1, getUserNameSucceed, getUserNameFailed, {msg: "this is a message"});
        }

        function getUserNameSucceed(result, ctx, methodName) 
{
            alert(result.UserId);
            alert(result.UserName);
        }
    因为 在UserSvc中的方法引用了UserInfo类,所以在客户端可以直接new UserInfo对象,并传递到服务端:
[WebMethod]
    
public bool Update(UserInfo info) {
        
// to update
        return true;
    }
    
function btnGetUserNameClickHandler() {
            var info 
= new UserInfo();
            info.UserId 
= 1;
            info.UserName 
= "guozhijian";
            UserSvc.Update(info, getUserNameSucceed, getUserNameFailed, 
{msg: "this is a message"});
        }
    如果UserSvc中的方法还没有引用到UserInfo类,而在客户端有想创建一个UserInfo对象,那么可以在UserSvc类定义加上一个Attribute:
[GenerateScriptType(typeof(UserInfo))]
    
    泛型支持:
[WebMethod]
    
public List<UserInfo> GetUsers() {
        
return new List<UserInfo>() {
            
new UserInfo() {UserId = 1, UserName = "guozhijian"},
            
new UserInfo() {UserId = 2, UserName = "zhenglanzhen"}
        }
;
    }
    
function btnGetUserNameClickHandler() {
            UserSvc.GetUsers(getUserNameSucceed, getUserNameFailed, 
{msg: "this is a message"});
        }

        function getUserNameSucceed(result, ctx, methodName) 
{
            
for(var i=0; i<result.length; i++{
                alert(result[i].UserId 
+ "," + result[i].UserName);
            }

        }

3. Page Method
    客户端js还可以调用在页面的后台代码页的方法:
[System.Web.Services.WebMethod()]
    
public static string GetUserName() {
        
return "Guozhijian";
    }
    必须定义为static

<asp:ScriptManager ID="sMgr" runat="server" EnablePageMethods="true"></asp:ScriptManager>
    
<div>
        
<input type="button" id="btnShowName" onclick="btnShowNameClickHandler()" value="show name" />
    
</div>
    必须设置scriptManager控件的 EnablePageMethods="true"

<script type="text/javascript">
        function btnShowNameClickHandler() 
{
            PageMethods.GetUserName(onSucceed,
null{msg : "this is a message"});
        }

        function onSucceed(result, ctx, methodName) 
{
            alert(result);
            alert(ctx.msg);
            alert(methodName);
        }

    
</script>
    通过PageMethods引用方法
posted on 2008-02-17 16:33  Tristan(GuoZhijian)  阅读(554)  评论(0编辑  收藏  举报