今天将NBear升级到v1.5.5,主要的升级一是新增了三个类EntitySerializer, OneToManyEntitySerializer, OneToOneEntitySerializer用于简化用户对序列化子件的使用,您不必再对着SerializerHelper提供给您的大堆序列化方法无所适从了。另一个重要的更新是集成了AjaxHelper - Teddy以前的Ajax实现到NBear。AjaxHelper原来的实现基于Prototype1.3.1,从Atlas beta出来起,Teddy已经很久没有更新了,因为我一直在思考AjaxHelper存在的必要性,如果存在,该突出什么。这次不是简单的Copy到NBear的目录,而是完整的集成,Ajax的实现核心也改用ASP.NET2.0内置的Callback代替prototype,主要的使用方式不变,请运行并参见下载后的源码的NBear.WebTest project的TestAjaxHelper.aspx,该页面包含了使用范例和简单说明。因为大致的使用方式没变,关于AjaxHelper的更多以前的AjaxHelper相关文章。
下载
您可以从这里下载最新版本的NBear v1.5.5
示例解析
TestAjaxHelper.aspx.cs
1
using
System;
2
using
System.Data;
3
using
System.Configuration;
4
using
System.Collections;
5
using
System.Web;
6
using
System.Web.Security;
7
using
System.Web.UI;
8
using
System.Web.UI.WebControls;
9
using
System.Web.UI.WebControls.WebParts;
10
using
System.Web.UI.HtmlControls;
11![](/Images/OutliningIndicators/None.gif)
12
public
partial
class
TestAjaxHelper : NBear.Web.UI.Page
13![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
14
protected override bool EnableAjaxCallback
15![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
16
get
17![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
18
return true;
19
}
20
}
21![](/Images/OutliningIndicators/InBlock.gif)
22
protected void Page_Load(object sender, EventArgs e)
23![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
24
}
25
}
![](/Images/OutliningIndicators/None.gif)
2
![](/Images/OutliningIndicators/None.gif)
3
![](/Images/OutliningIndicators/None.gif)
4
![](/Images/OutliningIndicators/None.gif)
5
![](/Images/OutliningIndicators/None.gif)
6
![](/Images/OutliningIndicators/None.gif)
7
![](/Images/OutliningIndicators/None.gif)
8
![](/Images/OutliningIndicators/None.gif)
9
![](/Images/OutliningIndicators/None.gif)
10
![](/Images/OutliningIndicators/None.gif)
11
![](/Images/OutliningIndicators/None.gif)
12
![](/Images/OutliningIndicators/None.gif)
13
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
14
![](/Images/OutliningIndicators/InBlock.gif)
15
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
16
![](/Images/OutliningIndicators/InBlock.gif)
17
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
18
![](/Images/OutliningIndicators/InBlock.gif)
19
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
20
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
21
![](/Images/OutliningIndicators/InBlock.gif)
22
![](/Images/OutliningIndicators/InBlock.gif)
23
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
24
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
25
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
注意Line14-20,如果希望当前page的AjaxHelper功能开启,必须像这样继承NBear.Web.UI.Page而不是默认的Page,并且重载EnableAjaxCallback属性,置为true。否则是访问不到AjaxHelper的API的。
TestAjaxHelper.aspx
1
<%
@ Page Language="C#" AutoEventWireup="true" CodeFile="TestAjaxHelper.aspx.cs" Inherits="TestAjaxHelper"
%>
2![](/Images/OutliningIndicators/None.gif)
3
<!
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
4![](/Images/OutliningIndicators/None.gif)
5
<
html
xmlns
="http://www.w3.org/1999/xhtml"
>
6
<
head
runat
="server"
>
7
<
title
>
Untitled Page
</
title
>
8
</
head
>
9
<
body
>
10
<
form
id
="form1"
runat
="server"
>
11
<
div
id
="output1"
></
div
>
12
<
br
/>
13
<
div
>
14![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
<
script
language
="javascript"
type
="text/javascript"
>
15
function OnComplete(content)
16![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
17
//you can deal with the return content here
18
alert(content);
19
}
20
</
script
>
21
<
input
type
="button"
value
="Callback & Updater using serverside created script handler"
onclick
="<%= Ajax.Updater("
controls/ctlHelloWorld", "output1", null, "alert") %
>
" />
<
br
/>
22
<
br
/>
23
<
input
type
="button"
value
="Callback Only using clientside created script handler"
onclick
="Ajax.Callback('controls/ctlHelloWorld', 'param1=1¶m2=22', OnComplete)"
/><
br
/>
24
<
br
/>
25
Both Ajax.Callback & Ajax.Updater have serverside and clientside version and can be writen like these two buttons.
<
br
/>
26
<
br
/>
27
The first param of Ajax.Callback and Ajax.Updater must be a UseControl inherits from NBear.Web.UI.AjaxTemplate, and u must override OnAjaxTemplatePreRender() and put init code in it to control what to display in the control.
<
br
/>
28
If u put code in Page_Load of this kind of controls, they will never be run.
<
br
/>
29
<
br
/>
30
You can deal with the callback return data in custom client script function like the 'OnComplete' function in this page.
<
br
/>
31
<
br
/>
32
The second param of Ajax.Callback can be "param1=1
&
param2=22" like params. Please use escape() to wrap this param before pass to serverside.
33
</
div
>
34
</
form
>
35
</
body
>
36
</
html
>
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
2
![](/Images/OutliningIndicators/None.gif)
3
![](/Images/OutliningIndicators/None.gif)
4
![](/Images/OutliningIndicators/None.gif)
5
![](/Images/OutliningIndicators/None.gif)
6
![](/Images/OutliningIndicators/None.gif)
7
![](/Images/OutliningIndicators/None.gif)
8
![](/Images/OutliningIndicators/None.gif)
9
![](/Images/OutliningIndicators/None.gif)
10
![](/Images/OutliningIndicators/None.gif)
11
![](/Images/OutliningIndicators/None.gif)
12
![](/Images/OutliningIndicators/None.gif)
13
![](/Images/OutliningIndicators/None.gif)
14
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
15
![](/Images/OutliningIndicators/InBlock.gif)
16
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
17
![](/Images/OutliningIndicators/InBlock.gif)
18
![](/Images/OutliningIndicators/InBlock.gif)
19
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
20
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
21
![](/Images/OutliningIndicators/None.gif)
22
![](/Images/OutliningIndicators/None.gif)
23
![](/Images/OutliningIndicators/None.gif)
24
![](/Images/OutliningIndicators/None.gif)
25
![](/Images/OutliningIndicators/None.gif)
26
![](/Images/OutliningIndicators/None.gif)
27
![](/Images/OutliningIndicators/None.gif)
28
![](/Images/OutliningIndicators/None.gif)
29
![](/Images/OutliningIndicators/None.gif)
30
![](/Images/OutliningIndicators/None.gif)
31
![](/Images/OutliningIndicators/None.gif)
32
![](/Images/OutliningIndicators/None.gif)
33
![](/Images/OutliningIndicators/None.gif)
34
![](/Images/OutliningIndicators/None.gif)
35
![](/Images/OutliningIndicators/None.gif)
36
![](/Images/OutliningIndicators/None.gif)
注意这里两个Button不同的onclick设置方式,两种方式等价可选的,也就是说客户端和服务段都有Ajax.Callback和Ajax.Updater函数,该页面的说明文字作了进一步解释。点击这个页面中的按钮时,callback将被触发,调用并显示controls/ctlHelloWorld.ascx中的内容。
ctlHelloWorld.ascx
1
<%
@ Control Language="C#" AutoEventWireup="true" CodeFile="ctlHelloWorld.ascx.cs" Inherits="controls_ctlHelloWorld"
%>
2![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
<%
# text
%>
<
br
/>
3
<
br
/>
4
<
asp:GridView
ID
="GridView1"
runat
="server"
>
5
</
asp:GridView
>
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
2
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
3
![](/Images/OutliningIndicators/None.gif)
4
![](/Images/OutliningIndicators/None.gif)
5
![](/Images/OutliningIndicators/None.gif)
注意,这里演示一个很简单的数据绑定,复杂绑定也是一样的。
ctlHelloWorld.ascx.cs
1
using
System;
2
using
System.Data;
3
using
System.Configuration;
4
using
System.Collections;
5
using
System.Web;
6
using
System.Web.Security;
7
using
System.Web.UI;
8
using
System.Web.UI.WebControls;
9
using
System.Web.UI.WebControls.WebParts;
10
using
System.Web.UI.HtmlControls;
11![](/Images/OutliningIndicators/None.gif)
12
public
partial
class
controls_ctlHelloWorld : NBear.Web.UI.AjaxTemplate
13![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
14
protected string text = "Hello World";
15![](/Images/OutliningIndicators/InBlock.gif)
16
public override void OnAjaxTemplatePreRender()
17![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
18
TestEntity obj = new TestEntity();
19
obj.ID = 1;
20
obj.Name = "test";
21![](/Images/OutliningIndicators/InBlock.gif)
22![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
GridView1.DataSource = new TestEntity[]
{ obj, obj, obj };
23![](/Images/OutliningIndicators/InBlock.gif)
24
DataBind();
25
}
26![](/Images/OutliningIndicators/InBlock.gif)
27
public class TestEntity
28![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
29
private int _ID;
30
private string _Name;
31![](/Images/OutliningIndicators/InBlock.gif)
32
public int ID
33![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
34
get
35![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
36
return _ID;
37
}
38
set
39![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
40
_ID = value;
41
}
42
}
43![](/Images/OutliningIndicators/InBlock.gif)
44
public string Name
45![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
46
get
47![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
48
return _Name;
49
}
50
set
51![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
52
_Name = value;
53
}
54
}
55
}
56
}
![](/Images/OutliningIndicators/None.gif)
2
![](/Images/OutliningIndicators/None.gif)
3
![](/Images/OutliningIndicators/None.gif)
4
![](/Images/OutliningIndicators/None.gif)
5
![](/Images/OutliningIndicators/None.gif)
6
![](/Images/OutliningIndicators/None.gif)
7
![](/Images/OutliningIndicators/None.gif)
8
![](/Images/OutliningIndicators/None.gif)
9
![](/Images/OutliningIndicators/None.gif)
10
![](/Images/OutliningIndicators/None.gif)
11
![](/Images/OutliningIndicators/None.gif)
12
![](/Images/OutliningIndicators/None.gif)
13
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
14
![](/Images/OutliningIndicators/InBlock.gif)
15
![](/Images/OutliningIndicators/InBlock.gif)
16
![](/Images/OutliningIndicators/InBlock.gif)
17
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
18
![](/Images/OutliningIndicators/InBlock.gif)
19
![](/Images/OutliningIndicators/InBlock.gif)
20
![](/Images/OutliningIndicators/InBlock.gif)
21
![](/Images/OutliningIndicators/InBlock.gif)
22
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
23
![](/Images/OutliningIndicators/InBlock.gif)
24
![](/Images/OutliningIndicators/InBlock.gif)
25
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
26
![](/Images/OutliningIndicators/InBlock.gif)
27
![](/Images/OutliningIndicators/InBlock.gif)
28
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
29
![](/Images/OutliningIndicators/InBlock.gif)
30
![](/Images/OutliningIndicators/InBlock.gif)
31
![](/Images/OutliningIndicators/InBlock.gif)
32
![](/Images/OutliningIndicators/InBlock.gif)
33
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
34
![](/Images/OutliningIndicators/InBlock.gif)
35
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
36
![](/Images/OutliningIndicators/InBlock.gif)
37
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
38
![](/Images/OutliningIndicators/InBlock.gif)
39
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
40
![](/Images/OutliningIndicators/InBlock.gif)
41
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
42
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
43
![](/Images/OutliningIndicators/InBlock.gif)
44
![](/Images/OutliningIndicators/InBlock.gif)
45
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
46
![](/Images/OutliningIndicators/InBlock.gif)
47
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
48
![](/Images/OutliningIndicators/InBlock.gif)
49
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
50
![](/Images/OutliningIndicators/InBlock.gif)
51
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/b854634c0904529d4018c4c3336be836.gif)
52
![](/Images/OutliningIndicators/InBlock.gif)
53
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
54
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
55
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
56
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
这里非常关键的是Line12和Line16-24,作为AjaxTemplate的usercontrol必须从NBear.Web.UI.AjaxTemplate继承,如果需要进行试数据初始化或者数据绑定,必须重载基类AjaxTemplate的OnAjaxTemplatePreRender()函数, 注意,这里不要将代码写在usercontrol的Page_Load里,否则当作为AjaxTemplate时不会被执行。
ok,示例介绍到这里,下面还是再说说AjaxHelper区别于一般的Ajax实现的设计思想!
AjaxHelper的特点
从AjaxHelper第一版开始,AjaxHelper就是以一种不太一样的形式出现的。尤其是在ASP.NET下,它使用ASP.NET的UserControl作为模版引擎,使得用户想通过ajax回调显示的内容可以直接借用usercontrol所具有的所有可视化设计、ASP.NET通用组件、尤其是数据绑定的便利,从而能够方便的将数据显示和操作分离,构成一个MVC的结构。AjaxHelper只是帮你传递模版的内容通过无刷新的异步callback获取数据,显示到页面上指定的位置或者交给用户来处理。这样就简化了传统的许多Ajax实现仅仅传递XML格式数据,或者需要在后台手工构造数据这样的非常依赖用户对数据的处理的问题。
配合NBear内置的 JSON实现,更能够使得基于现在的NBear的Ajax开发,拥有更强的服务端和客户端交互能力。就像NBear框架的整体形象一样,简单易用。尤其是这次集成后的AjaxHelper,简化了旧有版本的累赘的部分,完全无须例如httpmoudule或者在页面引用某个js文件等这样的配置,用户也可以选择是否enable,更不会无故增加页面的大小和服务器处理的负担。
如果你需要Ajax效果和传统的ASP.NET控件结合使用,或为原有项目增加Ajax效果,而不是将整个项目整体构架思路都基于Atlas这样的构架重写,那么AjaxHelpler同样会是一个不错的选择。