65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 AJAX 与 ASP.NET 2.0

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.64/5 (8投票s)

2008年7月13日

CPOL

4分钟阅读

viewsIcon

68950

downloadIcon

966

本文演示了如何将 AJAX 与 ASP.NET 2.0 结合使用。

引言

AJAX 是 Asynchronous JavaScript and XML 的缩写。它是目前网络程序员中最热门的词汇。它并非一项全新的技术,而是结合了 JavaScript 和 XML 等多项技术,实现了远程脚本。AJAX 使用客户端 JavaScript 和 XmlHttpRequest 对象向 Web 服务器发出异步请求,并在收到响应后映射一个要执行的函数。异步请求意味着浏览器在向服务器发送请求后无需等待响应。这样,无需将表单回发到服务器即可获取少量数据,从而创建了响应迅速的用户界面。

在本文中,我将演示一个类似 Google Suggest 的应用,当用户在文本框中输入文本时,会显示一个建议列表。

本文假定读者对 ASP.NET、C#、ADO.NET、JavaScript、XML 和 XSLT 有所了解。

以下是 ASP.NET AJAX 页面呈现时事件顺序的概述

  1. 呈现网页。
  2. 由触发器(例如 onKeyUp、按钮单击等)执行 JavaScript 函数。
  3. JavaScript 实例化一个 XMLHTTPRequest 对象。
  4. XMLHTTPRequest 对象调用一个远程页面。
  5. 远程页面使用 XSLT 转换 XML 结构并返回结果。
  6. JavaScript 接受结果并将其应用于页面。
  7. Web 页面通过从远程页面获取请求的数据来呈现,而无需回发到服务器。

创建 XMLHTTPRequest 对象

创建 XMLHTTPRequest 对象的方法因浏览器而异。IE 使用 ActiveX 技术实现此对象,而 Firefox、Opera 和 Safari 将其实现为原生对象。

此处提供的代码首先尝试为 Firefox、Safari 或 Opera 创建对象(objXmlHttp=new XMLHttpRequest();)。如果浏览器不是这些之一,它会尝试为 IE 6 及更高版本创建对象(objXmlHttp=new ActiveXObject("Msxml2.XMLHTTP");)。如果浏览器是 IE6 或更早版本,则对象将创建为 objXmlHttp=new ActiveXObject("Microsoft.XMLHTTP");。如果无法创建该对象,则会显示一个警告,提示浏览器不支持 AJAX。

function GetXmlHttpObject(handler) 
{
    var objXmlHttp;
    
    try
    { 
        // Firefox, Opera 8.0+, Safari  
        objXmlHttp=new XMLHttpRequest();  
        objXmlHttp.onload = handler; 
        objXmlHttp.onerror = handler; 
    }
    catch (e)
    {  
        // Internet Explorer6+  try
        try
        {
            objXmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); 
            objXmlHttp.onreadystatechange = handler;    
        }
        catch (e)
        {    
            try
            {      
                objXmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); 
                objXmlHttp.onreadystatechange = handler;         
            }
            catch (e)
            {      
                alert("Your browser does not support AJAX!");      
                return false;      
            }
        }
        return objXmlHttp;
    }

XMLHTTPRequest 对象属性

  • onreadystatechange - XMLHTTPRequest 对象的一个属性 onreadystatechange 被使用。这是响应处理函数,在 readyState 属性每次更改时都会被调用。
  • readyState - 接收请求的状态。
  • status - 服务器返回的 HTTP 状态码。
  • responseXML - 服务器返回的 XML 文档。

XMLHTTPRequest 对象方法

  • open - 初始化一个请求。
  • send - 将请求发送到服务器。

statechangehandler 函数

当状态更改时(即,收到数据时),stateChangeHandler 将触发。这是非阻塞的(异步的)。

function stateChangeHandler() 
{ 
    //readyState of 4 or 'complete' represents that data has been returned 
    if (xmlHttp.readyState == 4 || xmlHttp.readyState == 'complete')
    { 
        //Gather the results from the callback 
        var str = xmlHttp.responseText; 

        //Populate the innerHTML of the div with the results 
        document.getElementById('nameList').innerHTML = str;
    } 
    
    if (xmlHttp.readyState == 1)
    { 
        //Populate the innerHTML of the div with the results 
        document.getElementById('nameList').innerHTML = 'LOADING...';
    }
}

xmlHttp_Get 函数

创建请求并将其发送到服务器。

function xmlHttp_Get(xmlhttp, url) 
{ 
    xmlhttp.open('GET', url, true); 
    xmlhttp.send(null); 
}

完整的 JavaScript 代码如下:

var xmlHttp; 
var requestURL = 'Names.aspx?q='; 

function show_data(strName)
{ 
    if (strName.length > 0)
    { 
        //Append the name to search for to the requestURL 
        var url = requestURL + strName; 
         
        //Create the xmlHttp object to use in the request 
        //stateChangeHandler will fire when the state 
        //has changed, i.e. data is received back 
        // This is non-blocking (asynchronous) 
        xmlHttp = GetXmlHttpObject(stateChangeHandler); 
         
        //Send the xmlHttp get to the specified url 
        xmlHttp_Get(xmlHttp, url); 
    } 
    else 
    { 
        //Textbox blanked out, clear the results 
        document.getElementById('nameList').innerHTML = '';
    } 
}

//stateChangeHandler will fire when the state
//has changed, i.e. data is received back 
//This is non-blocking (asynchronous) 
function stateChangeHandler() 
{ 
    //readyState of 4 or 'complete' represents that data has been returned 
    if (xmlHttp.readyState == 4 || xmlHttp.readyState == 'complete')
    { 
        //Gather the results from the callback 
        var str = xmlHttp.responseText; 

        //Populate the innerHTML of the div with the results 
        document.getElementById('nameList').innerHTML = str;
    } 
    
    if (xmlHttp.readyState == 1)
    { 
        //Populate the innerHTML of the div with the results 
        document.getElementById('nameList').innerHTML = 'LOADING...';
    }
}

// XMLHttp send GET request 
function xmlHttp_Get(xmlhttp, url) 
{ 
    xmlhttp.open('GET', url, true); 
    xmlhttp.send(null); 
}

function GetXmlHttpObject(handler) 
{
    var objXmlHttp;
    
    try
    { 
        // Firefox, Opera 8.0+, Safari  
        objXmlHttp=new XMLHttpRequest();  
        objXmlHttp.onload = handler; 
        objXmlHttp.onerror = handler; 
    }
    catch (e)
    {  
        // Internet Explorer  try
        try
        {
            objXmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); 
            objXmlHttp.onreadystatechange = handler;    
        }
        catch (e)
        {    
            try
            {      
                objXmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); 
                objXmlHttp.onreadystatechange = handler;         
            }
            catch (e)
            {      
                alert("Your browser does not support AJAX!");      
                return false;      
            }
        }
        return objXmlHttp;
    }
}

HTML 文本框的 onKeyUp 属性会触发名为 show_data(string) 的函数,该函数会调用函数向远程页面发送请求。

客户端和远程页面

名为 Default.aspx 的客户端(可以是 Default.htm)包含发送请求到远程页面 Names.aspx 的 JavaScript。

完整的 JavaScript 放置在一个名为 AjaxGetNames.js 的外部脚本文件中。

JavaScript 请求会联系远程页面。变量“q”在查询字符串中传递,用于包含用户在文本框中键入的数据。根据该术语构造一个 XML 字符串。对 XML 数据应用 XSL 转换。

远程页面的 ADO.NET 代码查询 Northwind 数据库的 Customers 表,并查找与用户在文本框中键入的文本匹配的名称,在 div 标签中显示建议的名称。

using System;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml;
using System.Xml.Xsl;
using System.Xml.XPath;

public partial class Names : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Request.QueryString["q"] != null)
        {
            GetNames();
        }
    }
    
    private void GetNames()
    {
        string strQuery = Request.QueryString["q"];

        //Create the XML-like string to be sent back to the request 
        string strXmlNames = "";

        ArrayList al = new ArrayList();
        al = RetreiveNames();

        // Copies the elements of the ArrayList to a string array.
        String[] arrStrNames = (String[])al.ToArray(typeof(string));

        foreach (string strName in arrStrNames)
        {
            strXmlNames += "<user><name>" + strName + "</name></user>";
        }
        strXmlNames = "<users>" + strXmlNames + "</users>";

        //Create an XmlDocument object to store 
        //the XML string that we created 
        XmlDocument xDoc = new XmlDocument();
        xDoc.LoadXml(strXmlNames);

        //Create a navigator object to use in the XSL transformation 
        XPathNavigator xPathNav = xDoc.CreateNavigator();

        //Create the XSLTransform object 
        XslCompiledTransform xslt = new XslCompiledTransform();
        xslt.Load(Server.MapPath("Names.xslt"));

        //Do the transformation and send the results 
        //out to the Response object's output stream 
        xslt.Transform(xPathNav, null, Response.OutputStream);
        
    }

    public ArrayList RetreiveNames()
    {
        ArrayList al = new ArrayList();

        SqlConnection con = new SqlConnection();
        con.ConnectionString = 
            "Data Source=.;Integrated Security=True;Database=Northwind";

        SqlCommand cmd = new SqlCommand("SELECT ContactName from Customers" + 
                         " WHERE ContactName LIKE UPPER('" + 
                         Request.QueryString["q"] + "%')", con);
        
        con.Open();

        SqlDataReader rdr = cmd.ExecuteReader();

        while (rdr.Read())
        {
            al.Add(rdr[0].ToString());
        }
        return al;
    }
}

结论

在本文中,我演示了 AJAX 是一种利用 JavaScript 向服务器发起异步请求并处理来自服务器的 XML 响应的技术。演示了一个 ASP.NET 示例应用程序,该应用程序使用 AJAX 动态获取与数据库中的名称匹配的名称列表,而无需用户在文本框中键入文本时重新发布表单。通过这种方式,我说明了 AJAX 可以为 ASP.NET 网页提供更具响应性的用户界面。

© . All rights reserved.