本文主要列举了省市三级联动的DropDownList+Ajax的三种框架(aspnet/Jquery/ExtJs)示例。前段时间需要作一个的Web前端应用,需要用多个框架,一个典型的应用场景是省市三级联动,基于此应用,特将三种主要的ajax框架略作整理,方便有需要的朋友查阅。
在示例之前,我们先设置一个演示数据源,新建一个项目,项目结构如图:
主要文件如下:
AreaModel.cs:
- using System;
- using System.Collections.Generic;
- namespace Downmoon.Framework.Model
- {
- #region PopularArea
- public class Area
- {
- private string m_Area_ID;
- /// <summary>
- /// 地区编号
- /// </summary>
- public string Area_ID
- {
- get { return m_Area_ID; }
- set { m_Area_ID = value; }
- }
- private string m_Area_Name;
- /// <summary>
- /// 地区名称
- /// </summary>
- public string Area_Name
- {
- get { return m_Area_Name; }
- set { m_Area_Name = value; }
- }
- private double m_Area_Order;
- /// <summary>
- /// 排序
- /// </summary>
- public double Area_Order
- {
- get { return m_Area_Order; }
- set { m_Area_Order = value; }
- }
- private int m_Area_Layer;
- /// <summary>
- /// 层级
- /// </summary>
- public int Area_Layer
- {
- get { return m_Area_Layer; }
- set { m_Area_Layer = value; }
- }
- private string m_Area_FatherID;
- /// <summary>
- /// 父级ID
- /// </summary>
- public string Area_FatherID
- {
- get { return m_Area_FatherID; }
- set { m_Area_FatherID = value; }
- }
- public Area() { }
- public Area(string id, string name, double order, int layer, string father)
- {
- this.Area_ID = id;
- this.Area_Name = name;
- this.m_Area_Order = order;
- this.m_Area_Layer = layer;
- this.m_Area_FatherID = father;
- }
- }
- #endregion
- }
AreaControl.cs:
- using System;
- using System.Collections.Generic;
- using Downmoon.Framework.Model;
- namespace Downmoon.Framework.Controllers
- {
- public class AreaList : IArea
- {
- // Area singleton
- private static AreaList instance;
- public static AreaList Instance
- {
- get
- {
- if (AreaList.instance == null)
- {
- AreaList.instance = new AreaList();
- }
- return AreaList.instance;
- }
- }
- public List<Area> GetAreaList()
- {
- List<Area> Areas = new List<Area>();
- Areas.Add(new Area("110000", "北京市", 0, 1, "000000"));
- Areas.Add(new Area("110100", "市辖区", 0, 2, "110000"));
- Areas.Add(new Area("110101", "东城区", 0, 3, "110100"));
- Areas.Add(new Area("110102", "西城区", 0, 3, "110100"));
- Areas.Add(new Area("110103", "崇文区", 0, 3, "110100"));
- Areas.Add(new Area("330000", "浙江省", 0, 1, "000000"));
- Areas.Add(new Area("330100", "杭州市", 0, 2, "330000"));
- Areas.Add(new Area("330200", "宁波市", 0, 2, "330000"));
- Areas.Add(new Area("330102", "上城区", 0, 3, "330100"));
- Areas.Add(new Area("330103", "下城区", 0, 3, "330100"));
- Areas.Add(new Area("330104", "江干区", 0, 3, "330100"));
- Areas.Add(new Area("330105", "拱墅区", 0, 3, "330100"));
- Areas.Add(new Area("330106", "西湖区", 0, 3, "330100"));
- Areas.Add(new Area("330203", "海曙区", 0, 3, "330200"));
- Areas.Add(new Area("330204", "江东区", 0, 3, "330200"));
- Areas.Add(new Area("330205", "江北区", 0, 3, "330200"));
- Areas.Add(new Area("330206", "北仑区", 0, 3, "330200"));
- Areas.Add(new Area("330211", "镇海区", 0, 3, "330200"));
- return Areas;
- }
- public List<Area> GetAreaListFindByParentID(string filter)
- {
- return GetAreaList().FindAll(
- delegate(Area ar)
- {
- return ar.Area_FatherID == filter;
- }
- );
- }
- }
- }
Factory.cs
- using System;
- using System.Collections.Generic;
- //using Downmoon.Framework.Model;
- namespace Downmoon.Framework.Controllers
- {
- public class Factory
- {
- public static IArea GetAreaController()
- {
- return AreaList.Instance;
- }
- }
- }
IArea.cs
- using System;
- using System.Collections.Generic;
- using System.Text;
- using Downmoon.Framework.Model;
- namespace Downmoon.Framework.Controllers
- {
- public interface IArea
- {
- List<Area> GetAreaList();
- List<Area> GetAreaListFindByParentID(string filterID);
- }
- }
一、基于aspnet自带的Ajax框架,主要好处是与asp.net完全集成,无需写过多的js。缺点是在framework2下需作一些设置,在Framework 4下无需设置。
Framework 2:
需首先在web.config文件中作配置:
- <?xml version="1.0"?>
- <configuration>
- <configSections>
- <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
- <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
- <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>
- <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
- <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="Everywhere" />
- <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication" />
- <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication" />
- </sectionGroup>
- </sectionGroup>
- </sectionGroup>
- </configSections>
- <system.web>
- <customErrors defaultRedirect="" />
- <trace mostRecent="true" pageOutput="true" />
- <pages>
- <controls>
- <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
- </controls>
- </pages>
- <compilation>
- <assemblies>
- <add assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
- </assemblies>
- </compilation>
- <httpHandlers>
- <remove verb="*" path="*.asmx"/>
- <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
- <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
- <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false"/>
- </httpHandlers>
- <httpModules>
- <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
- </httpModules>
- </system.web>
- <system.webServer>
- <validation validateIntegratedModeConfiguration="false"/>
- <modules>
- <add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
- </modules>
- <handlers>
- <remove name="WebServiceHandlerFactory-Integrated" />
- <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode"
- type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
- <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode"
- type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
- <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
- </handlers>
- </system.webServer>
- </configuration>
前台页面:
- <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true">
- </asp:ScriptManager>
- <div>
- <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
- <ContentTemplate>
- <table width="500" border="0" cellpadding="0" cellspacing="2" >
- <tr>
- <td height="25" bgcolor="#EAEAEA" >
- 请选择省/市/区:
- </td>
- <td bgcolor="#f7f7f7">
- <asp:DropDownList ID="dpProvince" runat="server"
- AutoPostBack="true" onselectedindexchanged="dpProvince_SelectedIndexChanged" />
- <asp:DropDownList ID="dpCity" runat="server" AutoPostBack="true"
- onselectedindexchanged="dpCity_SelectedIndexChanged" />
- <asp:DropDownList ID="dpArea" runat="server" AutoPostBack="false"
- />
- </td>
- </tr>
- <tr>
- <td height="25" bgcolor="#EAEAEA" >
- </td>
- <td bgcolor="#f7f7f7">
- <asp:UpdateProgress ID="UpdateProgress1" runat="server">
- <ProgressTemplate>
- 正在查询,请稍候……………………</ProgressTemplate>
- </asp:UpdateProgress>
- </td>
- </tr>
- </table>
- </ContentTemplate>
- <Triggers>
- <asp:AsyncPostBackTrigger ControlID="dpProvince" EventName="SelectedIndexChanged" />
- <asp:AsyncPostBackTrigger ControlID="dpCity" EventName="SelectedIndexChanged" />
- </Triggers>
- </asp:UpdatePanel>
- </div>
Framework 4:与代码完全一样,只是无需在web.config中作配置。
如图:

二、基于JQuery1.4.1的Ajax框架,主要好处是与后续版本的asp.net完全集成。
基于ashx作一个Request,主要代码:
- using System;
- using System.Collections.Generic;
- using System.Web;
- using Downmoon.Framework.Controllers;
- using Downmoon.Framework.Model;
- using System.Text;
- namespace dropdown_JQuery14_Net2
- {
- /// <summary>
- /// Summary description for AjaxRequest
- /// </summary>
- public class AjaxRequest : IHttpHandler
- {
- public void ProcessRequest(HttpContext context)
- {
- string Area_FatherID = string.Empty;
- if (context.Request["pid"] != null)
- { Area_FatherID = context.Request["pid"].ToString(); }
- string parentId = string.Empty;
- //mydbDataContext db = new mydbDataContext();
- //根据传过来的Value值 进行查询
- //List<ChinaStates> list = db.ChinaStates.Where(c => c.ParentAreaCode == strId).ToList();
- List<Area> list = Factory.GetAreaController().GetAreaListFindByParentID(Area_FatherID);
- context.Response.ContentType = "application/json";
- context.Response.ContentEncoding = Encoding.UTF8;
- context.Response.Write(ListToJson(list));
- context.Response.End();
- }
- public string ListToJson(List<Area> list)
- {
- StringBuilder sb = new StringBuilder();
- if (list != null)
- {
- sb.Append("[");
- for (int i = 0; i < list.Count; i++)
- {
- sb.Append("{");
- sb.Append("\"Area_ID\":\"" + list[i].Area_ID + "\",");
- sb.Append("\"Area_Name\":\"" + list[i].Area_Name + "\"");
- //sb.Append("\"Area_FatherID\":\"" + list[i].Area_FatherID + "\"");
- if (i != list.Count - 1)
- {
- sb.Append("},");
- }
- }
- }
- sb.Append("}");
- sb.Append("]");
- return sb.ToString();
- }
- public bool IsReusable
- {
- get
- {
- return false;
- }
- }
- }
- }
前台:aspx
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head runat="server">
- <title></title>
- <style type="text/css">
- #dpCity
- {
- display: none;
- position: relative;
- }
- #dpArea
- {
- display: none;
- position: relative;
- }
- </style>
- <script language="javascript" type="text/javascript" src="Scripts/jquery-1.4.1.js"></script>
- </head>
- <body>
- <form id="form1" runat="server">
- <div>
- 请选择省/市/区: <asp:DropDownList ID="dpProvince" runat="server" />
- <asp:DropDownList ID="dpCity" runat="server">
- </asp:DropDownList>
- <asp:DropDownList ID="dpArea" runat="server" AutoPostBack="false" />
- </div>
- <script language="javascript" type="text/javascript">
- $(function () {
- var $dp1 = $("#dpProvince");
- var $dp2 = $("#dpCity");
- var $dp3 = $("select[name$=dpArea]");
- $dp1.focus();
- //alert($dpCity);
- loadAreas("000000", "0");
- $dp1.bind("change keyup", function () {
- if ($(this).val() != "") {
- //alert($("select option:selected").val());
- //loadAreas($("select option:selected").val(), "1");
- var strPid = $dp1.attr("value"); //获取城市
- loadAreas(strPid, "1");
- $dp2.fadeIn("slow");
- } else {
- $dp2.fadeOut("slow");
- }
- });
- $dp2.bind("change keyup", function () {
- var strCId = $dp2.attr("value"); //获取城市
- if ($(this).val() != "") {
- loadAreas(strCId, "2");
- $dp3.fadeIn("slow");
- } else {
- $dp3.fadeOut("slow");
- }
- });
- });
- function loadAreas(selectedItem, level) {
- $.getJSON("AjaxRequest.ashx?pid=" + selectedItem, function (data) {
- switch (level) {
- case "0":
- $("#dpProvince").html("");
- $("#dpProvince").append("<option value='' selected='selected'>请选择...</option>");
- for (var i = 0; i < data.length; i++) {
- $("#dpProvince").append($("<option></option>").val(data[i].Area_ID).html(data[i].Area_Name));
- };
- break;
- case "1":
- $("#dpCity").html("");
- $("#dpCity").append("<option value='' selected='selected'>请选择...</option>");
- for (var i = 0; i < data.length; i++) {
- $("#dpCity").append($("<option></option>").val(data[i].Area_ID).html(data[i].Area_Name));
- };
- break;
- case "2":
- $("#dpArea").html("");
- $("#dpArea").append("<option value='' selected='selected'>请选择...</option>");
- for (var i = 0; i < data.length; i++) {
- $("#dpArea").append($("<option></option>").val(data[i].Area_ID).html(data[i].Area_Name));
- };
- break;
- default:
- break;
- }
- });
- }
- </script>
- </form>
- </body>
- </html>


三、基于ExtJS 3.2的Ajax框架。
后台:
- using System;
- using System.Collections.Generic;
- using System.Web;
- using Downmoon.Framework.Controllers;
- using Downmoon.Framework.Model;
- using System.Text;
- namespace dropdown_ExtJS32_Net2.Ajax
- {
- /// <summary>
- /// Summary description for GetAreaXml
- /// </summary>
- public class GetAreaXml : IHttpHandler
- {
- //string baseCode = "000000";
- public void ProcessRequest(HttpContext context)
- {
- string parentId = "000000";
- if (context.Request["pid"] != null)
- {
- parentId = context.Request["pid"].ToString();
- }
- //parentId = (parentId.Length > 0) ? parentId : "000000";
- ////string parentId2 = "000000";
- ////if (context.Request["pid2"] != null)
- ////{
- //// parentId2 = context.Request["pid2"].ToString();
- ////}
- #region tony 2010.2.7 update
- List<Area> list = new List<Area>();
- //if (parentId.Length > 0)
- //{
- list = Factory.GetAreaController().GetAreaListFindByParentID(parentId);
- //}
- ////else if (parentId2.Length > 0)
- ////{
- //// list = Factory.GetAreaController().GetAreaListFindByParentID(parentId2);
- ////}
- #endregion
- context.Response.AddHeader("Cache-Control", "no-cache, must-revalidate");
- context.Response.ContentEncoding = System.Text.Encoding.UTF8;
- context.Response.ContentType = "text/html";
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < list.Count; i++)
- {
- sb.Append("{\"Area_Name\":\"" + list[i].Area_Name + "\",");
- sb.Append("\"Area_ID\":\"" + list[i].Area_ID + "\"},");
- }
- string json = sb.ToString().TrimEnd(',');
- context.Response.Write("{\"Results\":[" + json + "]}");
- }
- public bool IsReusable
- {
- get
- {
- return false;
- }
- }
- }
- }
前台页面.aspx
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head runat="server">
- <title>demo a dropdownlist by extjs 3.2 </title>
- <link rel="stylesheet" href="Scripts/ext/3.2/resources/css/ext-all.css" />
- <script type="text/javascript" src="Scripts/ext/3.2/adapter/ext/ext-base.js"></script>
- <script type="text/javascript" src="Scripts/ext/3.2/ext-all.js"></script>
- <script type="text/javascript">
- Ext.onReady(function () {
- //alert("extjs is Ok!");
- });
- function $() {
- return Ext.get(arguments[0]);
- }
- /*Area*/
- function GetAreas() {
- //alert($(arguments[1]));
- var cityCtrl = $(arguments[1]).child("select");
- var cityCtrlContainer = $(arguments[1]);
- cityCtrl.dom.options.length = 0;
- if ($(arguments[0]).getValue() == "") { cityCtrlContainer.hide(); return; }
- cityCtrl.disabled = true;
- var selectValue2 = $(arguments[0]).getValue();
- Ext.Ajax.request({
- url: arguments[2],
- params: { pid: selectValue2 },
- method: 'GET',
- success: function (result, request) {
- //alert(params);
- var jsonData = Ext.util.JSON.decode(result.responseText);
- //alert(jsonData.Results.length);
- if (jsonData.Results.length > 0) {
- cityCtrl.dom.options.add(new Option("请选择", "000000"));
- for (var i = 0; i < jsonData.Results.length; i++) {
- cityCtrl.dom.options.add(new Option(jsonData.Results[i].Area_Name, jsonData.Results[i].Area_ID));
- }
- cityCtrl.disabled = false;
- cityCtrlContainer.show();
- }
- else {
- cityCtrlContainer.hide();
- }
- },
- failure: function (result, request) { Ext.MessageBox.alert('Failed', 'Successfully posted form: ' + action.date); }
- });
- }
- </script>
- </head>
- <body>
- <form id="form1" runat="server">
- <table width="500" border="0" cellpadding="0" cellspacing="2">
- <tr>
- <td height="25" bgcolor="#EAEAEA">
- <div style="float: left; height: 20px; line-height: 20px;">
- 请选择</div>
- <asp:DropDownList Style="float: left;" ID="dropProvince" runat="server" />
- <div style="float: left; height: 20px; line-height: 20px;">
- 省</div>
- <asp:Panel ID="panelArea" runat="server">
- <asp:DropDownList Style="float: left;" ID="dropArea" runat="server" />
- <div style="float: left; height: 20px; line-height: 20px;">
- 市</div>
- </asp:Panel>
- <asp:Panel ID="panelArea2" runat="server" >
- <asp:DropDownList Style="float: left;" ID="dropArea2" runat="server" />
- <div style="float: left; height: 20px; line-height: 20px;">
- 县</div>
- </asp:Panel>
- </td>
- </tr>
- </table>
- </form>
- </body>
- </html>
效果如图:

