由于这里的用户数据不经常变化,考虑到搜索是需要频繁的向服务端请求数据,因此将用户数据存入了Application中,这样搜索时直接从Application中取,不用每次去数据库查询。
Application对象的赋值是在全局应用程序Global.asax的 Application_Start事件中完成的,代码如下:
复制代码 代码如下:
void Application_Start(object sender, EventArgs e)
{
Application.Lock();
Application["User"] = GetUsers();
Application.UnLock();
}
获取用户信息的GetUser方法中,同时完成了拼音简码的获取,代码如下:
复制代码 代码如下:
protected List<string> GetUsers()
{
List<Model.User> list = new BLL.User().GetUsers();
List<string> UserList = new List<string>();
foreach (Model.User item in list)
{
UserList .Add(item.Id+"|"+item.Name+"|"+GetPY(item.Name).Replace(" ","").ToLower());
}
return UserList ;
}
/// <summary>
/// 获得一个汉字字符的拼音的字符串集合,并处理声调和空值
/// </summary>
/// <param>汉字字符</param>
/// <returns></returns>
public static List<string> GetPinyins(char ch)
{
List<string> list = new List<string>();
Microsoft.International.Converters.PinYinConverter.ChineseChar cc = new Microsoft.International.Converters.PinYinConverter.ChineseChar(ch); //获得包含汉字信息的对象
foreach (string item in cc.Pinyins)
{
if (item != null)
{
string temp = item.Substring(0, item.Length - 1);
if (!list.Contains(temp))
{
list.Add(temp);
}
}
}
return list;
}
/// <summary>
/// 得到一个词组的拼音的首字母字符串(多音取第一个)
/// </summary>
/// <returns></returns>
public static string GetPY(string str)
{
Regex reg = new Regex(@"[\u4e00-\u9fa5]");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.Length; i++)
{
string ch = str[i].ToString();
if (string.IsNullOrEmpty(ch))
{
}
else if (reg.IsMatch(ch))
{
string s = GetPinyins(str[i])[0];
sb.Append(s[0]);
}
else
{
sb.Append(ch);
}
}
return sb.ToString();
}
至于Application与数据库中数据的一致的考虑,可提供一个一般处理程序UpdateApplication.ashx负责更新Application(代码与Global.asax中基本相同),当数据库发生变化时,访问UpdateApplication.ashx即可更新Application["Contact"]对象。
3.GetUser.ashx中返回符合检索条件的数据
GetUser.ashx中响应搜索事件的服务端代码清单如下:
复制代码 代码如下:
<%@ WebHandler Language="C#" %>
using System;
using System.Web;
using BLL;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Web.Script.Serialization;
using Microsoft.International.Converters.PinYinConverter;
public class GetUser :JavaScriptSerializer,IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
int i = 0;
List<string> strlist = context.Application["User"] as List<string>;
string inputStr = context.Request.QueryString.Get("term").ToLower();
List<UserItem> userList = new List<UserItem>();
foreach (string str in strlist)
{
string[] userArr = str.Split('|');
if (i < 10)
{
Regex reg = new Regex(@"^" + inputStr);
if (reg.IsMatch(userArr[2]) || reg.IsMatch(userArr[1]))
{
UserItem item = new UserItem();
item.id = userArr[0];
item.label = userArr[1];
item.value = userArr[2];
userList.Add(item);
i++;
}
}
else
{
break;
}
}
context.Response.ContentType = "application/json";
string output = Newtonsoft.Json.JsonConvert.SerializeObject(userList);
context.Response.Write(output);
}
public bool IsReusable
{
get
{
return false;
}
}
}
public class UserItem
{
public string id { get; set; }
public string label { get; set; }
public string value { get; set; }
}
第17行是获取文本框中输入的检索字符串inputstr,这里使用正则表达式对获取名称以inputstr开头的记录(中文检索)或者拼音简码以inputstr开头的记录(拼音检索)。如果需要模糊检索功能,可以修改第25行的正则表达式为:Regex reg = new Regex(inputStr);即可。如果需要更多字段的复合检索(例如用户手机号,邮箱地址等),也只要Application对像赋值时获取相关的字段信息,在26行的if判断中增加相应匹配项即可。