现在做网站都追求用户体验,那么ajax自然就必不可少。如果您用过Asp.Net MVC ,你会发现Asp.Net MVC 和jQuery 配合的非常默契(事实上jQuery已经成了微软的御用脚本库了),你可以用jQuery直接去异步加载一个PartialView(即.ascx用户控件)。如:$("#div").load("Controler/UserList.ascx");但是在webForm模式下就没这么幸福了,
如果你也这样去load一个用户控件,它会报错:"由于已明确禁止所请求的页类型,无法对该类型的页提供服务。扩展名“.ascx”可能不正确。 请检查以下的 URL 并确保其拼写正确"。
那我们就甘心放弃这样一种让人兴奋的方法,回去像以前那样一句一句的拼接字符串嘛?那样做不仅工作量大,而且繁琐易错,美工给的静态页面也不能拿来直接用,拼字符串时遇到引号还要转义。
我想,你肯定和我一样都不甘心放弃这种“load”方法,那我们就自己来实现吧。
首先设想一下,如果有这样一个类,它叫一PageProxy,这个类继承Page类,然后让我们的页面继承这个PageProxy类,而不是像默认的那样继承System.Web.UI.Page,
使我们在页面上能够直接load用户控件,那么如果我们要在哪个页面上异步load一个用户控件,我们就让那个页面继承这个PageProxy就行了。设想总是美好的,但要我们去实现。
那我们就去建有这样一个类吧,由于这个类是给其他类继承的,所以有 public abstract class PageProxy : Page。具体代码如下:
public
abstract
class
PageProxy : Page
{
///
<summary>
///
输出用户控件的Html片段
///
</summary>
///
<param name="control">
控件的相对路径
</param>
///
<returns></returns>
[WebMethod]
public
static
string
RenderUserControl(
string
control)
{
Page page
=
new
Page();
UserControl ctl
=
(UserControl)page.LoadControl(
"
~/
"
+
control);
page.Controls.Add(ctl);
StringWriter writer
=
new
StringWriter();
HttpContext.Current.Server.Execute(page, writer,
false
);
return
writer.ToString();
}
}
这个类只有一个webMethod方法,RenderUserControl,顾名思义,这个方法的功能是输出用户控件,也就是返回用户控件生成的html片断。
然后让我们的页面继承这个类,如:
public
partial
class
WebForm3 : PageProxy
{
//
.......
}
这样我们就可以用ajax访问这个方法了。到这里我们可以使用我
另一篇文章:甩掉 ashx/asmx,使用jQuery.ajaxWebService请求WebMethod,Ajax处理更加简练中封装的$.ajaxWebService(url, dataMap, fnSuccess)来访问这个方法了。
假如您已经了解了$.ajaxWebService(url, dataMap, fnSuccess),那现在比如我们要在一个div中加载一个叫UserList.ascx的用户控件:
$.ajaxWebService(
"
WebForm3/RenderUserControl
"
,
"
{control:'UserList.ascx'}
"
,
function
(result) {
$(
"
div
"
).html(result.d);
});
到这里我们的工作好像完成了,为什么说好像呢?因为我们还没有直接可以像这样$("div").load("UserList.ascx");简单的加载一个用户控件。
要实现这样其实也很简单只要给jQuery做个扩展,对上面的代码进行一下封装就OK了。代码如下:
//
/ <summary>
//
/ jQuery实例扩展,Ajax加载封装用户控件(*.ascx),输出Html,仅适用于Asp.Net。
//
/ 依赖 $.ajaxWebService(url, dataMap, fnSuccess)
//
/ </summary>
//
/ <param name="control" type="String">
//
/ 需要加载的用户控件的相对路径
//
/</param>
//
/ <param name="page" type="String">
//
/ 输出控件Html片段的页面,不一定是当前页面。可选,缺省值为当前页面。
//
/</param>
$.fn.loadUserControl
=
function
(control, page) {
var
$dom
=
this
;
if
(page
==
""
||
page
==
null
) {
page
=
location.pathname.replace(
"
/
"
,
""
);
}
page
+=
"
/RenderUserControl
"
;
//
RenderUserControl是PageProxy中的方法,不要轻易修改
$.ajaxWebService(page,
"
{control:'
"
+
control
+
"
'}
"
,
function
(result) {
$dom.html(result.d);
});
}
其中第一个参数control必选,第二个参数page可选。
这时我们再加载UserList.ascx,就可以这样写了: $("div").loadUserControl("UserList.ascx");
这也是我们最终要的效果。
到此我们的实现就全部完成了。
下面给出一个完整的示例代码:
PageProxy.cs:
public
abstract
class
PageProxy : Page
{
[WebMethod]
public
static
string
RenderUserControl(
string
control)
{
Page page
=
new
Page();
UserControl ctl
=
(UserControl)page.LoadControl(
"
~/
"
+
control);
page.Controls.Add(ctl);
StringWriter writer
=
new
StringWriter();
HttpContext.Current.Server.Execute(page, writer,
false
);
return
writer.ToString();
}
}
WebForm3.aspx.cs:
public
partial
class
WebForm3 : PageProxy
{
protected
void
Page_Load(
object
sender, EventArgs e)
{
}
}
jquery.extend.js:
//
/ <summary>
//
/ jQuery原型扩展,重新封装Ajax请求WebServeice
//
/ </summary>
//
/ <param name="url" type="String">
//
/ 处理请求的地址
//
/</param>
//
/ <param name="dataMap" type="String">
//
/ 参数,json格式的字符串
//
/</param>
//
/ <param name="fnSuccess" type="function">
//
/ 请求成功后的回调函数
//
/</param>
$.ajaxWebService
=
function
(url, dataMap, fnSuccess) {
$.ajax({
type:
"
POST
"
,
contentType:
"
application/json
"
,
url: url,
data: dataMap,
dataType:
"
json
"
,
success: fnSuccess
});
}
//
/ <summary>
//
/ jQuery实例扩展,Ajax加载封装用户控件(*.ascx),输出Html,仅适用于Asp.Net。
//
/ 依赖 $.ajaxWebService(url, dataMap, fnSuccess)
//
/ </summary>
//
/ <param name="control" type="String">
//
/ 需要加载的用户控件的相对路径
//
/ </param>
//
/ <param name="page" type="String">
//
/ 输出控件Html片段的页面,不一定是当前页面。可选,缺省值为当前页面。
//
/ </param>
$.fn.loadUserControl
=
function
(control, page) {
var
$dom
=
this
;
if
(page
==
""
||
page
==
null
) {
page
=
location.pathname.replace(
"
/
"
,
""
);
}
page
+=
"
/RenderUserControl
"
;
//
RenderUserControl是PageProxy中的方法,不要轻易修改
$.ajaxWebService(page,
"
{control:'
"
+
control
+
"
'}
"
,
function
(result) {
$dom.html(result.d);
});
}
WebForm3.aspx:
<%
@ Page Language
=
"
C#
"
AutoEventWireup
=
"
true
"
CodeBehind
=
"
WebForm3.aspx.cs
"
Inherits
=
"
WebFormjQuery.WebForm3
"
%>
<!
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
>
WebForm下使用jQuery.loadUserControl异步load用户控件
</
title
>
<
script
src
="Scripts/jquery-1.3.2.js"
type
="text/javascript"
></
script
>
<
script
src
="Scripts/jquery.extend.js"
type
="text/javascript"
></
script
>
<
script
type
="text/javascript"
>
function
loadUserList(){
$(
"
#div_userList
"
).loadUserControl(
"
Controls/UserList.ascx
"
);
}
</
script
>
</
head
>
<
body
>
<
form
id
="form1"
runat
="server"
>
<
div
>
<
div
><
input
type
="button"
value
="加载用户列表(用户控件)"
onclick
="loadUserList()"
/></
div
>
<
div
id
='div_userList'
></
div
>
</
div
>
</
form
>
</
body
>
</
html
>
PersonOM:
public
class
PersonOM
//
model类,作为demo,我们就懒得建数据库了
{
public
string
Name {
get
;
set
; }
public
int
Age {
get
;
set
; }
}
UserList.ascx://待加载的用户控件
<%
@ Control Language
=
"
C#
"
AutoEventWireup
=
"
true
"
CodeBehind
=
"
UserList.ascx.cs
"
Inherits
=
"
WebFormjQuery.Controls.UserList
"
EnableViewState
=
"
false
"
%>
<%
@ Import Namespace
=
"
System.Collections.Generic
"
%>
<
ul
>
<%
List
<
PersonOM
>
lstps
=
WebForm1.GetResult();
%>
<%
foreach ( PersonOM ps in lstps)
{
%>
<
li
>
姓名:
<%
=
ps.Name
%>
年龄:
<%
=
ps.Age
%>
</
li
>
<%
}
%>
</
ul
>
源码下载
原文地址:http://www.cnblogs.com/xumingxiang/archive/2010/05/04/1727614.html