码迷,mamicode.com
首页 > Web开发 > 详细

AJAX简洁教程

时间:2015-07-13 07:48:32      阅读:158      评论:0      收藏:0      [点我收藏+]

标签:

介绍

尽管AJAX是种客户端技术,但实际上的开发过程,它经常要调用一个服务器端的过程。通常,网站上的数据是存放在一个关系型数据库中,为了让AJAX更有用处,处理服务器端数据需要一种简单可靠的方法。幸运的是,ASP.NET AJAX提供了一种有效的基础架构来做这件事情,浏览器和服务器在Internet上可以进行AJAX通信。自然而然,Web Service在数据传输和客户端/服务器之间的一般通信方面可以扮演一个重要角色。本文就演示了如果通过ASP.NET AJAX调用ASP.NET web services

软件需求

本文所有的范例都是使用ASP.NET AJAX RC版,而且,要在SQL Server 2005 (Express版即可)上有一个Northwind数据库。范例使用Visual Studio 2005作为开发环境。

范例场景

范例开发了一个Web页面,用于输入Northwind数据库职员表中的职员数据。页面通过ASP.NET AJAX功能,调用一个Web Service来完成职员表中的数据增、删、改、查。

 

创建一个Web Service

 

作为开始,使用Visual Studio 2005创建一个新的Web站点,注意把ASP.NET AJAX项目模板添加到新站点对话框,这个对话框包括一个"ASP.NET AJAX Enabled Web Site" 模板。

 

新站点创建模板

 

使用"ASP.NET AJAX Enabled Web Site" 模板创建的新站点和用普通方法创建的站点区别如下:

 

   ·它的Web.config自动包括许多ASP.NET AJAX专用的配置信息。

 

   ·System.Web.Extensions程序集被添加到引用中。

 

当然,我们可以更改一个普通的Web站点,以使之符合AJAX要求,但模板可以大大简化我们的工作。

 

现在我们创建了一个新的Web站点,添加一个新的web service并命名为EmployeeService.asmxEmployeeService将包括5Web方法

 

Method Name

Description

GetEmployees()

返回Employees表里的雇员列表。 这个列表是一个Employee对象数组

GetEmployee()

接收EmployeeID参数返回Employee对象的详细信息

Insert()

Employees表里增加一个新的雇员信息

Update()

更新Employees表里的某个雇员信息

Delete()

删除Employees表里的某个雇员信息

 

                                                                             表EmployeeService中的Web方法

 

GetEmployees() 和 GetEmployee()方法以Employee对象的形式返回数据,因此,首先创建一个Employee类。

右键单击App_Code文件夹,选择添加新项…”,添加一个叫Employee的类,下面显示Employee类的全部代码:

public class Employee

{

   private int intEmployeeID;

   private string strFirstName;

   private string strLastName;

   public int EmployeeID

   {

      get

      {

         return intEmployeeID;

      }

      set

      {

         intEmployeeID = value;

      }

   }

   public string FirstName

   {

      get

      {

         return strFirstName;

      }

      set

      {

         strFirstName = value;

      }

   }

   public string LastName

   {

      get

      {

         return strLastName;

      }

 

      set

      {

         strLastName = value;

      }

   }

}

 

Employee类申明三个Private变量来分别存放employee ID, first name和 last name,三个变量再封装在三个public属性中:EmployeeID, FirstNameLastName

 

打开 web.config文件,添加<connectionStrings>部分如下:

<connectionStrings>

   <add name="connstr" connectionString=

        "data source=.\sqlexpress;

        initial catalog=northwind;

        integrated security=true"/>

</connectionStrings>

 

这部分存放数据库链接字符串,用于指向Northwind数据库,确保修改SqlServer名称、IP地址以及验证方式以和我们的开发环境相符。

 

现在,打开EmployeeService.cs添加如下代码:

private string strConn =   "";

public EmployeeService()

{

   strConn = ConfigurationManager.ConnectionStrings["connstr"].

             ConnectionString;

}

 

代码使用了ConfigurationManager类来读取配置文件中的数据库链接字符串,并存放在一个类级别的变量strConn中,这个变量将被下面的所有Web Method所使用。

 

现在,添加GetEmployees() web method

[WebMethod]

public Employee[] GetEmployees()

{

   SqlConnection cnn = new SqlConnection(strConn);

   cnn.Open();

   SqlCommand cmd            = new SqlCommand();

  cmd.Connection            = cnn;

   cmd.CommandText           = "select employeeid,firstname,

                                lastname from employees";

   SqlDataReader reader      = cmd.ExecuteReader();

   List<Employee> list = new List<Employee>();

   while (reader.Read())

   {

      Employee emp   = new Employee();

      emp.EmployeeID = reader.GetInt32(0);

      emp.FirstName  = reader.GetString(1);

      emp.LastName   = reader.GetString(2);

      list.Add(emp);

   }

   reader.Close();

   cnn.Close();

   return list.ToArray();

}

 

代码创建了SqlConnection and SqlCommand 对象,然后执行SELECT查询,以获取Employees表中EmployeeID, FirstName LastName字段。结果通过SqlDataReader返回。然后,创建一个generic-based Employee数组,通过While循环,给每个Employee实例的属性赋值。当While循环完毕的时候,关闭SqlDataReader 和 SqlConnectionGetEmployees()方法返回的类型是Employee数组。因此,generic List使用List类中的ToArray()方法来转换成Employee数组。

 

现在,添加一个GetEmployee() web method如下:

[WebMethod]

public Employee GetEmployee(int pEmployeeId)

{

   SqlConnection cnn = new SqlConnection(strConn);

   cnn.Open();

   SqlCommand cmd       = new SqlCommand();

 

   cmd.Connection       = cnn;

   cmd.CommandText      = "select employeeid,firstname,lastname

                           from employees where employeeid=@id";

   SqlParameter id      = new SqlParameter("@id", pEmployeeId);

   cmd.Parameters.Add(id);

   SqlDataReader reader = cmd.ExecuteReader();

   Employee emp         = new Employee();

   while (reader.Read())

   {

      emp.EmployeeID = reader.GetInt32(0);

 

   emp.FirstName  = reader.GetString(1);

      emp.LastName   = reader.GetString(2);

   }

   reader.Close();

   cnn.Close();

   return emp;

}

 

GetEmployee() web method接受一个employee ID参数作为输入,代码和前面的非常相似,但这次只返回一个employee。注意,使用SqlParameter来定义传入的EmployeeID

 

现在,再添加Insert()Update()和 Delete()web methods,其中,Insert() web method 以要添加的Employee的 first name 和 last name 作为参数,Update() web method 以要更新的employee ID 以及新的first name 和 last name作为参数,并执行UPDATE语句, Delete() web method 以要删除的employee ID 作为参数,然后执行DELETE 语句

[WebMethod]

public int Insert(string pFirstName, string pLastName)

{

   SqlConnection cnn  = new SqlConnection(strConn);

   cnn.Open();

   SqlCommand cmd     = new SqlCommand();

   cmd.Connection     = cnn;

   cmd.CommandText    = "insert into employees(firstname,lastname)

                         values (@fname,@lname)";

   SqlParameter fname = new SqlParameter("@fname", pFirstName);

   SqlParameter lname = new SqlParameter("@lname", pLastName);

   cmd.Parameters.Add(fname);

   cmd.Parameters.Add(lname);

   int i = cmd.ExecuteNonQuery();

   cnn.Close();

   return i;

}

[WebMethod]

public int Update(int pEmployeeId,string pFirstName, string pLastName)

{

   SqlConnection cnn  = new SqlConnection(strConn);

   cnn.Open();

   SqlCommand cmd     = new SqlCommand();

   cmd.Connection     = cnn;

   cmd.CommandText    = "update employees set firstname=@fname,

                         lastname=@lname where employeeid=@id";

   SqlParameter fname = new SqlParameter("@fname", pFirstName);

  SqlParameter lname = new SqlParameter("@lname", pLastName);

   SqlParameter id = new SqlParameter("@id", pEmployeeId);

   cmd.Parameters.Add(fname);

   cmd.Parameters.Add(lname);

   cmd.Parameters.Add(id);

   int i = cmd.ExecuteNonQuery();

   cnn.Close();

   return i;

}

[WebMethod]

public int Delete(int pEmployeeId)

{

   SqlConnection cnn = new SqlConnection(strConn);

   cnn.Open();

   SqlCommand cmd  = new SqlCommand();

   cmd.Connection  = cnn;

   cmd.CommandText = "delete from employees where employeeid=@id";

   SqlParameter id = new SqlParameter("@id", pEmployeeId);

   cmd.Parameters.Add(id);

   int i = cmd.ExecuteNonQuery();

   cnn.Close();

   return i;

}

这就完成了web service的创建。到目前为止,还没有做任何和AJAX特性相关的任何工作,现在,时机已经成熟,我们通过下面的代码更改web service类的定义:

using System.Web.Script.Services;

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

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

[ScriptService]

public class EmployeeService : System.Web.Services.WebService

{

注意特地标明的黑体字,我们导入了System.Web.Script.Services命名空间,这个命名空间来自System.Web.Extensions程序集,这个命名空间提供了[ScriptService]属性,这将使web service可以被来自客户端的JavaScript (ASP.NET AJAX)调用。

 

好了,我们开始准备从ASP.NET AJAX调用Web Service了!

 

 

如何调用Web Service

 这部分,我们将创建一个Web页面作为数据输入,通过调用刚刚创建的Web Service来操作Employees表。作为开始,我们先添加一个EmployeeServiceClient.aspx页面,打开工具箱,选择View > Toolbox菜单,在工具箱上,选中AJAX Extensions这样的节点,增加模板后的新站点创建对话框.

 AJAX Extensions部分显示一个Web页面上所有可以使用的ASP.NET AJAX组件。所有使用ASP.NET AJAX的页面都需要一个ScriptManager组件。打开ScriptManager属性窗口,定位Services属性,打开Service引用编辑器,Service 引用编辑器.

 

 点击对话框底部的Add按钮,设置Path属性以指向Web ServiceEmployeeService.asmx)的虚拟路径,下面的标记将会产生在Web页面文件中:

 

<asp:ScriptManager ID="ScriptManager1" runat="server" >

 <Services>

      <asp:ServiceReference Path="EmployeeService.asmx" />

   </Services>

</asp:ScriptManager>

 

对每个Web Service调用,都需要在<asp:ScriptManager>部分添加一个<asp:ServiceReference>元素,此标记把要使用的web service注册到当前web form上。

 

表单包括一个下拉框(<SELECT>) ,用于显示所有的employee IDs,一旦选中其中一个employee IDemployee的详细信息将显示在2个文本框中,然后可以更新这些信息。如果要添加一个employee,只需要输入first name 和 last name,然后点击插入按钮就可以了。同理,如果要删除一个employee,选择下拉框中的employee ID,点击删除按钮。在INSERTUPDATE或者 DELETE操作完成后,将会显示成功或者失败的信息。下面是所有的页面代码:

 

<table>

 

   <tr>

 

      <td colspan="2">

 

         <asp:Label ID="Label4" runat="server" Font-Size="X-Large"

 

                    Text="Employee Management">

 

         </asp:Label></td>

 

   </tr>

 

   <tr>

 

      <td style="width: 100px">

 

         <asp:Label ID="Label1" runat="server"

 

                    Text="Employee ID :"></asp:Label></td>

 

      <td style="width: 100px">

 

         <select id="Select1" >

 

         </select>

 

      </td>

 

   </tr>

 

   <tr>

 

      <td style="width: 100px">

      <asp:Label ID="Label2" runat="server"

                    Text="First Name :"></asp:Label></td>

      <td style="width: 100px">

         <input id="Text1" type="text" /></td>

   </tr>

   <tr>

      <td style="width: 100px">

         <asp:Label ID="Label3" runat="server"

                    Text="Last Name :"></asp:Label></td>

      <td style="width: 100px">

         <input id="Text2" type="text" /></td>

   </tr>

   <tr>

      <td align="center" colspan="2">

         <input id="Button3" type="button" value="Insert" />

         <input id="Button4" type="button" value="Update" />

         <input id="Button5" type="button" value="Delete" />

      </td>

   </tr>

   <tr>

      <td align="center" colspan="2">

         <span id="lblMsg" style="font-weight: bold;

               color: red;"></span>

      </td>

   </tr>

</table>

 

注意:我们没有使用ASP.NET服务器端控件,如DropDownList、 TextBox 以及 Button。取而代之的是,我们用的传统的HTML控件,如:<SELECT> 以及 <INPUT>。这因为我们要想通过客户端JavaScript调用web service,而不是通过服务端代码。同理,注意底下的<SPAN>标记,这是用来显示成功或者失败的信息的。

 

下一步,在<head>元素内增加一个<script>部分,添加一个CallWebMethod()的函数:

 

function CallWebMethod(methodType)

 

{

 

   switch(methodType)

 

   {

 

      case "select":

 

         EmployeeService.GetEmployees(FillEmployeeList,ErrorHandler,

 

                                      TimeOutHandler);

 

         break;

 

      case "selectone":

 

         var select=document.getElementById("Select1");

     var empid=select.options[select.selectedIndex].value;

         EmployeeService.GetEmployee(empid,DisplayEmployeeDetails,

                                     ErrorHandler,TimeOutHandler);

         break;

      case "insert":

         var text1=document.getElementById("Text1");

         var text2=document.getElementById("Text2");

         EmployeeService.Insert(text1.value,text2.value,

                                InsertEmployee,ErrorHandler,

                                TimeOutHandler);

         break;

      case "update":

         var select=document.getElementById("Select1");

         var empid=select.options[select.selectedIndex].value;

         var text1=document.getElementById("Text1");

         var text2=document.getElementById("Text2");

         var emp=new Employee();

         emp.EmployeeID=empid;

         emp.FirstName=text1.value;

         emp.LastName=text2.value;

         EmployeeService.Update(empid,text1.value,text2.value,

                                UpdateEmployee,ErrorHandler,

                                TimeOutHandler);

         break;

      case "delete":

         var select=document.getElementById("Select1");

         var empid=select.options[select.selectedIndex].value;

         EmployeeService.Delete(empid,DeleteEmployee,ErrorHandler,

                                TimeOutHandler);

         break;

   }

}

 

CallWebMethod() 函数 就是用来调用web service的中央控制函数。 这个函数接收一个字符串参数用来标识调用的方法,它包括一个switch 语句来判断调用的方法,每个 case 块 调用一个web method。 注意web method 是如何被调用的:ASP.NET AJAX 框架自动创建一个JavaScript 代理类,这个代理类和要调用的web service有相同的名称。因此,上面代码中 EmployeeService 并不是真正的 类,而是一个JavaScript 代理类。 代理类包括原始web service中所有的Web Method。除了原来的web method 所包括的参数外,每个方法还包括3个额外的参数。

第一个参数是一个JavaScript 函数,用于当web method 成功完成时调用的。记住:所有客户端和服务器端的AJAX 通信都是异步的,因此,这个函数用来捕获web method 的返回值。第二个参数是用于发生错误的情况下调用的JavaScript 函数。最后,第三个参数是当调用Web Service 发生超时的情况下调用的JavaScript 函数。

 

第一种情况,case ("select"),就是简单的调用GetEmployees() 方法;第二种情况,case ("selectone"),调用GetEmployee()方法,通过传统的JavaScript 代码获取下拉框中的employee ID;同理,第三、第四、第五个Case依次调用Insert()、 Update()和 Delete()方法。

 

上面的代码通过5JavaScript函数实现相应的web method 成功调用:FillEmployeeList(), DisplayEmployeeDetails(), InsertEmployee(), UpdateEmployee()以及 DeleteEmployee()。每个函数接收一个参数作为web method相应的返回值。

 

function FillEmployeeList(result)

 

{

 

   var select=document.getElementById("Select1");

 

   for(var i=0;i<result.length;i++)

 

   {

 

      var option=new Option(result[i].EmployeeID,

 

                            result[i].EmployeeID);

 

      select.options.add(option);

 

   }

 

}

 

function DisplayEmployeeDetails(result)

 

{

 

   var text1=document.getElementById("Text1");

 

   var text2=document.getElementById("Text2");

 

   text1.innerText=result.FirstName;

 

   text2.innerText=result.LastName;

 

   var lblMsg=document.getElementById("lblMsg");

 

   lblMsg.innerText="";

 

}

 

function InsertEmployee(result)

 

{

 

   if(result>0)

 

   {

 

      var lblMsg=document.getElementById("lblMsg");

 

      lblMsg.innerText="Employee added successfully!";

 

   }

 

   else

 

   {

 

      var lblMsg=document.getElementById("lblMsg");

 

      lblMsg.innerText="Error occurred while adding new employee!";

 }

}

function UpdateEmployee(result)

{

   if(result>0)

   {

      var lblMsg=document.getElementById("lblMsg");

      lblMsg.innerText="Employee updated successfully!";

   }

   else

   {

      var lblMsg=document.getElementById("lblMsg");

      lblMsg.innerText="Error occurred while updating the employee!";

   }

}

function DeleteEmployee(result)

{

   if(result>0)

   {

      var lblMsg=document.getElementById("lblMsg");

      lblMsg.innerText="Employee deleted successfully!";

   }

   else

   {

      var lblMsg=document.getElementById("lblMsg");

      lblMsg.innerText="Error occurred while deleting employee!";

   }

}

 

FillEmployeeList() 函数以Employee对象数组作为输入参数,还记得GetEmployees() web method 返回的Employee对象数组吧。然后对这个数组迭代处理,在每次迭代中,一个新的OPTION元素被创建并添加到下拉框中。DisplayEmployeeDetails()函数以一个Employee对象作为输入,这个Employee对象包括了一个Employee的详细信息,并显示在2个文本框中。InsertEmployee(), UpdateEmployee()DeleteEmployee()函数以一个整型的数值标明INSERT, UPDATEDELETE操作所影响的记录数,一个大于0的数值标明操作成功,并在<SPAN>标记内显示一个成功的信息;否则,显示一个错误信息。当页面第一次加载时,需要用现有的employee ID给下拉框赋值,这得通过调用一个特定的名为pageLoad()的函数中实现:

function pageLoad()

{

   CallWebMethod("select");

}

 

 

pageLoad()函数在客户端浏览器页面加载时自动调用,最后,错误处理(error handler)和超时处理(timeout handler)函数如下:

function ErrorHandler(result)

{

   var msg=result.get_exceptionType() + "\r\n";

   msg += result.get_message() + "\r\n";

   msg += result.get_stackTrace();

   alert(msg);

}

function TimeOutHandler(result)

{

   alert("Timeout :" + result);

}

 

TimeOutHandler() 函数在任何web method 调用发生超时的情况下调用。它仅仅显示了一个Alert给用户。 ErrorHandler() 函数在有错误发生的情况下调用,其输入result 参数提供了3个方法:get_exceptionType()get_message()以及 get_stackTrace()。这三个方法分别返回异常类型(type of exception)、详细错误信息 和堆栈跟踪(stack trace)。这里ErrorHandler()函数也仅仅显示了一个alert给终端用户。

测试网页

现在,我们已经实现了web service和客户端应用程序。测试一下吧!运行网页,试着增加、更新、删除一个employee看看,显示更新一个employee后的效果:

 

要想测试错误处理函数,把初始化数据库链接字符串改成一个空值,然后运行网页看看,这次,就会显示一个警报(alert),

 

调用外部Web Services

 

这个例子中,EmployeeService也是Web站点的一部分。有时候,我们的程序也许需要调用根本就没有部署在我们的域的web services。 ASP.NET AJAX内部需要依赖XML HTTP 对象,而由于安全原因,是不能和部署在其它外部站点进行通信的。这就意味着上面所说的技术对外部的web services调用无效。不幸的是,ASP.NET AJAX关于此问题还没有直接的解决方案(至少在RC版本)。然而,微软发布了一个仍在CTP阶段的“Bridge”技术,我们可以使用此技术来调用一个部署在本地的封装(Wrapper)的类,然后在这个类中来调用外部的实际的Web Service。在当前的RC版本中,我们可以在我们的Web Site中创建一个Wrapper Web Service,以它来调用最初的Web Service。然后在客户端程序中通过调用Wrapper Web Service实现通信。下面显示必要的步骤:

 

1. web站点中添加一个web引用,指向外部的Web service

 

2. 创建一个本地Web service

 

3. 在新创建的Web service中,提供封装的web method,这些方法调用外部的Web Method

 

4. 用本文中所说的方法在客户端应用程序中调用本地新添加的web Service

 

调用ASP.NET Web Services的基础架构

 

ASP.NET AJAX提供了完整的架构以从客户端JavaScript调用ASP.NET web services。我们可以轻松地用AJAX把服务器端数据集成进用户响应的Web页面中。而我们所需要做的就是仅仅用[ScriptService]属性来标识web ServiceASP.NET AJAX 框架会为我们的web service自动生成JavaScript代理,然后通过使用代理来调用web methods

 

AJAX简洁教程

标签:

原文地址:http://www.cnblogs.com/JiSuiFeng/p/4641970.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!