程序列表17.定义页面方法
[WebMethod] public static Customer[] GetCustomersByCountry(string country) { return Biz.BAL.GetCustomersByCountry(country); } [WebMethod] public static Customer[] GetCustomersByID(string id) { return Biz.BAL.GetCustomersByID(id); }
ScriptManager 检测到页面中有 Web 方法时,将生成一个指向前面提到的PageMethods 对象的动态引用。调用 Web Method 是通过引用 PageMethods 类来实现的。PageMethods 类后面跟的是方法的名称以及任何需要传递的参数。程序列表18 中的示例是调用前面展示的两个页面方法。
程序列表18.用PageMethods JavaScript对象调用页面方法
function GetCustomerByCountry() { var country = $get("txtCountry").value; PageMethods.GetCustomersByCountry(country, OnWSRequestComplete); } function GetCustomerByID() { var custID = $get("txtCustomerID").value; PageMethods.GetCustomersByID(custID, OnWSRequestComplete); } function OnWSRequestComplete(results) { var searchResults = $get("searchResults"); searchResults.control.set_data(results); if (results != null) GetMap(results[0].Country,results); }
补充:
using System.Web.Services; public partial class Default2 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } /// <summary> /// WebService 创建和使用页面方法 /// </summary> /// <returns></returns> [WebMethod] public static string HelloWorld() { return "Hello World"; } }
PageMethods 对象的使用与 JavaScript 代理对象的使用非常相似。首先指定应传递给页面方法的所有参数数据,然后定义应在异步调用返回时调用的回调函数。也可指定回调失败(参见程序列表14 的失败处理示例)。
AutoCompleteExtender及 ASP.NET AJAX 工具箱ASP.NET AJAX 工具箱(可从 获取)提供了多种可用于访问Web 服务的控件。具体地说,工具箱包含一个名为AutoCompleteExtender 的有用控件,可用于调用Web 服务并在页面中显示数据而无需编写任何JavaScript 代码。
AutoCompleteExtender控件可用于扩展文本框的现有功能,并帮助用户更轻松地定位到要查找的数据。通过在文本框中输入内容,用户可使用此控件查询Web 服务并在文本框下方动态显示结果。图4 中的示例是使用 AutoCompleteExtender 控件为一个支持应用程序显示客户id。当用户在文本框中输入不同字符时,下方将根据输入内容显示不同条目。然后用户便可以从中选择所需的客户id。
在 ASP.NET AJAX 页面中使用AutoCompleteExtender,要求在网站的 bin 文件夹中添加AjaxControlToolkit.dll程序集。一旦添加了工具箱程序集,您将需要在web.config 中引用它,以便它包含的控件可供应用程序中的所有页面使用。在web.config 的 <controls> 标记中添加如下标记即可:
<add namespace="AjaxControlToolkit" assembly="AjaxControlToolkit" tagPrefix="ajaxToolkit"/>
如果您只需要在特定页面中使用控件,可以通过在页面顶端添加Reference 指示符来引用(如下所示),而非更新web.config:
AutoCompleteExtender有几个不同的属性,包括服务器控件上的 standard ID 和runat 属性。除了这些属性外,此控件还可用于定义在向Web 服务查询数据之前终端用户可输入的字符数。程序列表19 中的MinimumPrefixLength 属性使得每向文本框中输入一个字符就调用一次服务。要谨慎设置此属性值,因为每次用户输入一个字符,都将调用Web 服务以搜索与文本框内字符匹配的值。要调用的Web 服务和目标 Web 方法是分别使用 ServicePath 和 ServiceMethod 属性定义的。最后,TargetControlID 属性识别要将 AutoCompleteExtender 控件与哪个文本框挂钩。
调用的 Web 服务必须象前面内容描述的那样应用了 ScriptService 属性,且目标Web 方法必须接受名为prefixText 和count 的两个属性。prefixText 参数表示终端用户输入的字符,而count 参数表示要返回条目的数量(默认为10)。程序列表 20 中的示例是程序列表 19 中的 AutoCompleteExtender控件调用的GetCustomerIDs Web服务。Web 方法调用一个业务层方法,后者又调用一个处理数据筛选并返回匹配结果的数据层方法。数据层方法的代码如程序列表21 所示。
程序列表20.从AutoCompleteExtender控件发出的筛选数据
[WebMethod] public string[] GetCustomerIDs(string prefixText, int count) { return Biz.BAL.GetCustomerIDs(prefixText, count); }
程序列表21.基于终端用户输入的筛选结果
public static string[] GetCustomerIDs(string prefixText, int count) { //Customer IDs cached in _CustomerIDs field to improve performance if (_CustomerIDs == null) { List<string> ids = new List<string>(); //SQL text used for simplicity...recommend using sprocs string sql = "SELECT CustomerID FROM Customers"; DbConnection conn = GetDBConnection(); conn.Open(); DbCommand cmd = conn.CreateCommand(); cmd.CommandText = sql; DbDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { ids.Add(reader["CustomerID"].ToString()); } reader.Close(); conn.Close(); _CustomerIDs = ids.ToArray(); } int index = Array.BinarySearch(_CustomerIDs, prefixText, new CaseInsensitiveComparer()); //~ is bitwise complement (reverse each bit) if (index < 0) index = ~index; int matchingCount; for (matchingCount = 0; matchingCount < count && index + matchingCount < _CustomerIDs.Length; matchingCount++) { if (!_CustomerIDs[index + matchingCount].StartsWith(prefixText, StringComparison.CurrentCultureIgnoreCase)) { break; } } String[] returnValue = new string[matchingCount]; if (matchingCount > 0) { Array.Copy(_CustomerIDs, index, returnValue, 0, matchingCount); } return returnValue; }
补充:
aspx