使用ASP.NET AJAX异步调用Web Service和页面中的类方法
分类:计算机教程

接下来即可用ASP.NET AJAX异步调用这个Web Service了。首先新建一个ASP.NET页面。当然,该页面所在的Web站点必须已经配置好了ASP.NET AJAX的支持,详细配置方法请参考本书第I卷。在该页面上添加一个ScriptManager服务器端控件,这是每一个ASP.NET AJAX应用程序都必不可少的:

总结:想要让ASP.NET AJAX异步通讯层为服务器端复杂类型自动生成相应的客户端JavaScript类型,并在调用过程中传递并接收该复杂类型,我们需要:

参考:ASP.NET AJAX异步通讯层为Web Service自动生成的客户端代理以及相应的回调函数还提供了更多的参数和配置功能,这些都将在本章中详细介绍。

图3-21 忽略Salary属性后客户端Employee类型的结构

这样即完成了本示例程序,运行一下,我们将会看到如图3-1和图3-2一样的界面。

美洲杯赔率 1

  1. 将该方法声明为公有(public);
  2. 将该方法声明为类方法(C#中的static,VB.NET中的Shared),而不是实例方法;
  3. 为该方法添加[WebMethod]属性;
  4. 将页面中ScriptManager控件的EnablePageMethods属性设置为true;
  5. 在客户端使用如下JavaScript语法调用该页面方法:
    PageMethods.[MethodName](param1, param2 …, callbackFunction);
  6. 为客户端异步调用指定回调函数,在回调函数中接收返回值并进一步处理。
private int m_salary;

[System.Web.Script.Serialization.ScriptIgnore]

public int Salary

{

    get { return m_salary; }

    set { m_salary = value; }

}

总结:想要使用ASP.NET AJAX在客户端JavaScript中异步调用定义在ASP.NET页面中的方法,我们需要:

public class Employee

{

    private int m_id;

    public int Id

    {

        get { return m_id; }

        set { m_id = value; }

    }

 

    private string m_name;

    public string Name

    {

        get { return m_name; }

        set { m_name = value; }

    }

 

    private string m_email;

    public string Email

    {

        get { return m_email; }

        set { m_email = value; }

    }

 

    private int m_salary;

    public int Salary

    {

        get { return m_salary; }

        set { m_salary = value; }

    }

 

    public Employee()

    {

    }

 

    public Employee(int id, string name, string email, int salary)

    {

        m_id = id;

        m_name = name;

        m_email = email;

        m_salary = salary;

    }

}

提示:我们也可以直接为需要暴露给客户端的Web Service方法添加[ScriptService]属性,而不必将其添加到Web Service类上。

前面四个<input />分别将用来显示某个Employee对象的Id、Name、Email以及Salary属性,并提供了对这些属性的编辑功能。后面两个<input />作为按钮,将分别调用前面Web Service中定义的CreateNewEmployee()和SaveEmployee()两个方法的客户端代理。

注意上述代码中的粗体部分。可以看到,调用页面方法代理时统一的前缀为PageMethods。接下来是页面方法的名称,这里为SayHelloFromPage(),其参数列表和C#中方法的定义一致,额外的一个参数表示本次异步调用的回调函数。即语法为:

然后在ASP.NET页面中添加ScriptManager控件以及相应的Web Service的引用:

<input id="tbName" type="text" />

<input id="btnInvoke" type="button" value="Say Hello" 

    onclick="return btnInvoke_onclick()" />

<div id="result"></div>

复杂类型

function btnInvoke_onclick() {

    var theName = $get("tbName").value;

    SimpleWebService.SayHello(theName, onSayHelloSucceeded);

}

页面的UI部分代码非常直观:


编辑好这4个条目之后,点击“Save”按钮,将触发btnSave_onclick()事件处理函数。btnSave_onclick()事件处理函数以及相应的回调函数如下:

上面代码中btnInvoke按钮定义了click事件的事件处理函数,该函数的实现如下。注意这是客户端JavaScript代码:

提示:在实际开发中,我们也可以直接使用客户端Employee类的构造函数,在客户端直接构造出一个Employee对象,而不必总是从服务器端取得程序中需要的新对象,以便提高应用程序的整体性能:

<asp:ScriptManager ID="sm" EnablePageMethods="true" runat="server" />

btnNew_onclick()事件处理函数以及相应的回调函数如下:

[ScriptService]属性位于System.Web.Script.Services命名空间中,如果需要的话,还要添加如下的using语句:

图3-18 点击“Create New”按钮之后,程序将从服务器端取得一个新的Employee对象

随后声明程序界面中必不可少的UI元素:

var employeeInEditing = null;
[WebService(Namespace = "http://tempuri.org/")]

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

public class SimpleWebService : System.Web.Services.WebService

{

    [WebMethod]

    public string SayHello(string name)

    {

        return string.Format("Hello {0}!", name);

    }

}

图3-19 SaveEmployee()方法接收到的从客户端传入的Employee对象

借助于ASP.NET AJAX异步通讯层所自动生成的Web Service客户端访问代理,在表现层代码,也就是JavaScript中调用Web Service获取数据成为了一件异常简单的事情——其表现出的优雅甚至让我们不敢相信:难道Ajax程序也能写得这么简单?

function btnNew_onclick() {

    PeopleManagementService.CreateNewEmployee(onCreated);

}

 

function onCreated(result) {

    employeeInEditing = result;

    $get("tbId").value = employeeInEditing.Id;

    $get("tbName").value = employeeInEditing.Name;

    $get("tbEmail").value = employeeInEditing.Email;

    $get("tbSalary").value = employeeInEditing.Salary;

}

之所以ASP.NET AJAX将Web Service提高到了如此的重要位置上,让它几乎成为了ASP.NET AJAX服务器端逻辑最受推荐的实现方式,是因为Web Service天生就是纯粹为了业务逻辑而设计的。我们都知道,Web Service没有提供什么“花哨”的用户界面,而是心无旁骛地专注于程序逻辑上的实现,这恰好和ASP.NET AJAX客户端编程模型所倡导的“将表现层和业务逻辑层彻底分开”的理念不谋而合——客户端的ASP.NET AJAX框架用来处理程序所有的界面、与用户交互功能,服务器端则仅仅提供纯粹的数据,不涉及任何表现样式。

在服务器端SaveEmployee()方法成功返回后,客户端onSaved()回调函数将在页面中弹出提示对话框。如图3-20所示。

让客户端JavaScript直接能够异步调用到服务器端的Web Service,这看起来真的是个不错的主意——理想化的分层Ajax应用程序就应该这样嘛!不过作为被ASP.NET服务器端开发模型“宠坏”了的我们,更加熟悉的方法是直接将方法写在ASP.NET页面中,比如处理页面中的某个服务器端按钮Click事件的代码,就可能这样调用定义在同一张页面代码文件中的方法:

图3-16 Employee类的类图

图3-2 程序显示出来自服务器的问候信息

美洲杯赔率 2

ASP.NET AJAX的异步通讯层在本示例程序中小试牛刀,纵观整个示例程序的实现代码,我们不难看出该架构的强大功能以及为我们开发者细心周全的考虑。虽然在实际开发中,我们很难遇到本示例程序中这样简单的功能。但麻雀虽小,五脏俱全,理解了这样一个简单的示例程序之后,我们完全可以举一反三,根据开发过程中的实际需要编写不同的Web Service以及客户端调用代码,轻松地完成工作。

  1. 会把没有应用[System.Web.Script.Serialization.ScriptIgnore]的公有属性(property)或公有字段(field)映射到客户端JavaScript类型中;
  2. 不会把该复杂类型的私有字段映射到客户端JavaScript类型中;
  3. 不会把该复杂类型的方法(method)映射到客户端JavaScript类型中;

其中id为tbName的<input />作为文本框,用来让用户输入名字;id为btnInvoke的<input />作为按钮,点击将触发异步调用Web Service;id为result的<div />则用来将Web Service返回的问候内容显示出来。这些id均将在稍后用到。

var em = new Employee();

程序将借助ASP.NET AJAX异步通讯层以Ajax方式把用户的名字发送至服务器端的Web Service。随后该Web Service在服务器端根据用户的名字生成一段问候信息并发送回客户端,客户端收到服务器响应之后,将把这段问候信息显示出来,如图3-2所示。

CreateNewEmployee()和SaveEmployee()方法都不能完成什么具体的工作,仅仅起到演示功能。PeopleManagementService所应用的[GenerateScriptType(typeof(Employee))]属性(上述代码中的粗体部分)才是完成程序功能的关键之处,该属性定义于System.Web.Script.Services命名空间中。若我们希望让ASP.NET AJAX异步通讯层为某一复杂类型生成客户端的JavaScript对应类型,以便完成服务器和客户端之间的通讯,则应该用GenerateScriptType属性显式声明。

美洲杯赔率,让我们先从服务器端的Web Service入手。新建一个名为SimpleWebService的Web Service类并在其中声明一个普通的Web Service方法——SayHello()。该方法将接受一个名为name的参数,并生成一条问候信息返回:

然后,ASP.NET AJAX异步通讯层在为某服务器端复杂类型生成客户端JavaScript类型时,将:

using System;

using System.Web;

using System.Web.Services;

using System.Web.Services.Protocols;

using System.Web.Script.Services;

 

[WebService(Namespace = "http://tempuri.org/")]

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

[ScriptService]

public class SimpleWebService : System.Web.Services.WebService

{

    [WebMethod]

    public string SayHello(string name)

    {

        return string.Format("Hello {0}!", name);

    }

}
var myObj = new [NameSpace].[ClassName]();

而本示例程序中按钮的click事件处理函数以及异步调用的回调函数则需要一定的修改,如下所示:

我们也可以使用如下语法在客户端直接创建该复杂类型:

  1. 为Web Service类或需要暴露给客户端的Web Service方法添加[ScriptService]属性;
  2. 为Web Service中需要暴露给客户端的方法添加[WebMethod]属性;
  3. 在页面中的ScriptManager控件中添加对该Web Service的引用;
  4. 在客户端使用如下JavaScript语法调用该Web Service:
    [NameSpace].[ClassName].[MethodName](param1, param2 ......, callbackFunction)
  5. 为客户端异步调用指定回调函数,在回调函数中接收返回值并进一步处理。

若想传递某些复杂的数据类型,比如某个自定义类型或结构,那么我们要显式告知ASP.NET AJAX异步通讯层为该服务器端类型生成相应的客户端JavaScript类型。

接下来就让我们通过一个简单的示例程序了解一下在ASP.NET AJAX应用程序中使用JavaScript异步调用Web Service的方法。出于演示的目的,程序的功能非常简单:用户在页面的文本框中输入名字,然后点击旁边的按钮,如图3-1所示。

ASP.NET AJAX异步通讯层能够很好地支持这个需求,我们所要做的只是为Employee类中的Salary属性添加[System.Web.Script.Serialization.ScriptIgnore]属性,修改后的Salary属性如下,注意其中粗体部分:

美洲杯赔率 3

美洲杯赔率 4

我们还是通过一个实例程序来了解这个功能。该示例程序的功能与界面均与前面一节中的完全一致,唯一的不同就是,客户端异步调用的不再是某个Web Service,而是定义在ASP.NET页面中的类方法。

图3-17 客户端Employee类型的结构

本文来自《ASP.NET AJAX程序设计 第II卷:客户端Microsoft AJAX Library相关》的第三章《异步调用Web Service和页面中的类方法》,请同时参考本章的其他文章。

注意:实际上,对于“最外层”(即在Web Service方法的参数或返回值出现过)的复杂类型,[GenerateScriptType(typeof([TypeName]))]属性并不是强制要求的。但若是最外层复杂类型中还嵌套有内层的复杂类型,比如Employee中有个属性指向的是另一个复杂类型——Manager(这个Manager类型即为嵌套复杂类型),那么我们就一定要显式为Web Service添加[GenerateScriptType(typeof([Manager]))]属性。或者某Web Service方法的参数或返回值为List<Employee>(将在稍后介绍),那么我们也要为Web Service添加[GenerateScriptType(typeof([Employee]))]属性。

function btnInvoke_onclick() {

    var theName = $get("tbName").value;

    PageMethods.SayHelloFromPage(theName, onSayHelloSucceeded);

}

 

function onSayHelloSucceeded(result) {

    $get("result").innerHTML = result;

}

上面代码中的employeeInEditing为全局变量,用来保存当前正被编辑的客户端Employee对象,定义在这两个函数之外:

3.2 调用页面中的类方法

回调函数将服务器端新创建的Employee对象的4个属性值分别显示在页面中的4个文本框中,供用户编辑。如图3-18所示。

好在ASP.NET AJAX在设计时考虑到了这个问题,并提供给我们一种作为替代的选择。ASP.NET AJAX异步通讯层能够将声明在ASP.NET页面中的公有的类方法(C#中的static,VB.NET中的Shared)当作Web Service中声明的方法一样对待,为其生成类似的客户端调用代理。

 

[WebService(Namespace = "http://tempuri.org/")]

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

[GenerateScriptType(typeof(Employee))]

[ScriptService]

public class PeopleManagementService : System.Web.Services.WebService

{

    [WebMethod]

    public Employee CreateNewEmployee()

    {

        return new Employee(0, string.Empty, string.Empty, 0);

    }

 

    [WebMethod]

    public bool SaveEmployee(Employee em)

    {

        // 保存到数据库中...

 

        return true;

    }

}

本文由美洲杯赔率发布于计算机教程,转载请注明出处:使用ASP.NET AJAX异步调用Web Service和页面中的类方法

上一篇:Javascript的声明美洲杯赔率 下一篇:没有了
猜你喜欢
热门排行
精彩图文
  • Bootstrap 2.2.2 发布,重要的 Bug 修复版本
    Bootstrap 2.2.2 发布,重要的 Bug 修复版本
    今天我们发布了 Bootstrap 2.2.2, 这是另外一个很大的 bugfix版本,主要是侧重于 CSS 和文档方面的问题修复,也有很小一部分的JS问题,主要包括: Docs: Asset
  • 每天一个linux命令 chgrp命令
    每天一个linux命令 chgrp命令
    [root@localhost test]# ll---xrw-r-- 1 root root 302108 11-13 06:03 log2012.log[root@localhost test]# chgrp -v bin log2012.log“log2012.log” 的所属组已更改为 bin[root@localhost test]# ll---xr
  • 我是如何跨专业零基础学习Python爬虫的(2 爬虫所
    我是如何跨专业零基础学习Python爬虫的(2 爬虫所
    列表是Python中最基本的数据结构,列表是最常用的Python数据类型,列表的数据项不需要具有相同的类型。列表中的每个元素都分配一个数字 2. Python 列表
  • TCP socket如何判断连接断开
    TCP socket如何判断连接断开
    自己做了一个tcp工具,在学习动画的时候踩了坑,需求是根据上线变绿色,离线变灰色,如果连接断开了,则变为灰色 http://blog.csdn.net/zzhongcy/article/detail
  • golang新手们容易犯的3个错误总结
    golang新手们容易犯的3个错误总结
    这是因为golang中变量的作用域范围小到每个词法块(不理解的同学可以简单的当成{}包裹的部分)都是一个单独的作用域,大家都知道每个作用域的内部声