用asp.net开发Ajax有两种主流,一种是微软推出的技术,其中一个最常用的就是UpdatePanel控件,还有一种是AjaxPro技术。
这种技术有着各自的特点。采用微软的技术开发也沿用了微软一贯的简单化、傻瓜化的特点,开发简单Ajax程序几乎不需要了解任何网页脚本知识和 XHTML知识,缺点也有一些,通常会带来一些不必要的网络流量(整个UpdatePanel控件内所有的控件内容都会提交),另外在VS2005下经常会出现“***不是已知元素 原因可能是网站中存在编译错误 ”的提示,虽然有治标不治本的办法(见拙作:***不是已知元素 原因可能是网站中存在编译错误 中提到的解决办法),但是经常出现这种提示,也够让人心烦的。
而AjaxPro的起点较高,需要开发人员孰知Js脚本知识和XHTML相关知识,因为所有的方法需要你自己编写网页脚本。开发速度相对会较慢一点,调试也会困难一点(JS调试就是麻烦)。
网上有不少讲述怎么使用AjaxPro调用服务器端方法的例子,我大概看了一下,估计只有一个原本,然后被Copy了N遍,所以到处都是,可惜的是那篇文章里没有降到如何把客户端的数据传送到服务器,比如我想在用户注册时那个用户名是否被注册了,怎么办?
查看了网上雷同的N篇文章之后没有找到答案,后来自己琢磨了很久,才琢磨出来,下面展示一下用法。
<%
@ Page Language
=
"
C#
"
AutoEventWireup
=
"
true
"
CodeFile
=
"
Test.aspx.cs
"
Inherits
=
"
Test
"
%>
<!
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
>
</
head
>
<
body
>
<
form
id
="form1"
runat
="server"
>
<
div
>
<
table
width
="95%"
border
="0"
align
="center"
cellpadding
="3"
cellspacing
="1"
bordercolor
="#FFFFFF"
style
="border-collapse: collapse"
>
<
tr
align
="center"
>
<
td
height
="20"
colspan
="2"
>
</
td
>
</
tr
>
<
tr
class
="tdbg"
>
<
td
width
="50%"
><
b
>
用户名:
</
b
><
BR
>
不能超过14个字符(7个汉字)
</
td
>
<
td
width
="50%"
align
="left"
>
<
asp:TextBox
ID
="txtUserName"
runat
="server"
CssClass
="input"
Columns
="30"
MaxLength
="14"
onblur
="javascript:checkName();void(0);"
></
asp:TextBox
><
div
id
="errorMsg"
></
div
><
font
color
="#FF0000"
>
*
</
font
>
</
td
>
</
tr
>
<
tr
class
="tdbg"
>
<
td
width
="50%"
><
strong
>
年龄:
</
strong
></
td
>
<
td
width
="50%"
align
="left"
>
<
asp:TextBox
ID
="txtAge"
runat
="server"
CssClass
="input"
Columns
="30"
MaxLength
="50"
onblur
="javascript:checkAge();void(0);"
></
asp:TextBox
><
div
id
="errorMsg1"
></
div
></
td
>
</
tr
>
</
table
>
</
div
>
<
script
language
="javascript"
type
="text/javascript"
defer
="defer"
>
function
checkName()
{
var
name
=
document.getElementById(
"
<%=txtUserName.ClientID %>
"
);
document.getElementById(
"
errorMsg
"
).style.display
=
"
block
"
;
document.getElementById(
"
errorMsg
"
).style.color
=
"
red
"
;
document.getElementById(
"
errorMsg
"
).innerText
=
Test.CheckUserName(
""
+
name.value
+
""
).value;
}
function
checkAge()
{
var
age
=
document.getElementById(
"
<%=txtAge.ClientID %>
"
);
document.getElementById(
"
errorMsg1
"
).style.display
=
"
block
"
;
document.getElementById(
"
errorMsg1
"
).style.color
=
"
red
"
;
document.getElementById(
"
errorMsg1
"
).innerText
=
Test.CheckAge(parseInt(age)).value;
}
</
script
>
</
form
>
</
body
>
</
html
>
后台代码:Test.cs
using
System;
using
System.Data;
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;
/*
*
* 写作说明:本文展示了如何利用AjaxPro与服务器交互,并且给服务器传值的情况。
* 作者:周公
* 日期:2008-1-1
* 首发地址:
http://blog.csdn.net/zhoufoxcn/
*
*/
public
partial
class
Test : System.Web.UI.Page
{
protected
void
Page_Load(
object
sender, EventArgs e)
{
if
(
!
Page.IsPostBack)
{
}
AjaxPro.Utility.RegisterTypeForAjax(
typeof
(Test));
//
注册
}
[AjaxPro.AjaxMethod]
public
string
CheckUserName(
string
name)
{
if
(
string
.IsNullOrEmpty(name))
{
return
"
请填写用户名
"
;
}
else
if
(ExistUserName(name))
{
return
"
该用户名已被注册
"
;
}
else
{
return
"
可以注册
"
;
}
}
[AjaxPro.AjaxMethod]
public
string
CheckAge(
int
age)
{
if
(age
>
80
||
age
<
10
)
{
return
"
别忽悠我了
"
;
}
else
{
return
"
正常范围
"
;
}
}
//
为简化程序,这里将从数据库检查是否有重复的用户名这一步简单为一个方法
//
可以在这里写实际的数据库检查代码
private
bool
ExistUserName(
string
name)
{
if
(name.StartsWith(
"
a
"
)
||
name.StartsWith(
"
c
"
))
{
return
true
;
}
else
{
return
false
;
}
}
}
说明:在前台aspx代码中我们写了两个Js方法,负责与服务器的交互,分别是function checkName()和checkAge(),请注意看:
<
script language
=
"
javascript
"
type
=
"
text/javascript
"
defer
=
"
defer
"
>
function
checkName()
{
var
name
=
document.getElementById(
"
<%=txtUserName.ClientID %>
"
);
.......省略无关代码
document.getElementById(
"
errorMsg
"
).innerText
=
Test.CheckUserName(
""
+
name.value
+
""
).value;
}
function
checkAge()
{
var
age
=
document.getElementById(
"
<%=txtAge.ClientID %>
"
);
.......省略无关代码
document.getElementById(
"
errorMsg1
"
).innerText
=
Test.CheckAge(parseInt(age.value)).value;
}
</
script
>
细心的朋友会发现在后台Test.cs里就有CheckUserName(string name)和public string CheckAge(int age)两个方法,在js里我们就是通过Test.CheckUserName()和Test.CheckAge()来调用的,这两个服务器端方法与平常所熟悉的方法声明有点不一样,如下:
[AjaxPro.AjaxMethod]
public
string
CheckUserName(
string
name)
{
....
//
方法体略
}
[AjaxPro.AjaxMethod]
public
string
CheckAge(
int
age)
{
....
//
方法体略
}
其中[AjaxPro.AjaxMethod]表明它们是可以被js代码所调用的,另外两个方法需要的参数类型不同,一个是string类型,一个是int类型,而js中数据没有类型的,因为都是var来声明的,所以如何把参数值和参数类型传给服务器还是一个麻烦问题。
查阅了资料,发现可以通过上述的方式解决:
Test.CheckUserName( "" + name.value + "" ),服务器就自动把参数值当字符串类型来识别了;//""+参数值
Test.CheckAge(parseInt(age)),服务器就会把参数当整数来识别了。//parseInt(参数值)
看看运行效果:
出错效果:
正常效果:
最后,周公还要提醒大家一下,别忘了在Page_Load方法里调用AjaxPro.Utility.RegisterTypeForAjax(typeof(你的aspx页面所依附的class名称));这句话。另外有关AjaxPro的介绍请参考网上其它资料。