[转载]WebForm下使用 jQuery.loadUserControl异步load用户控件

现在做网站都追求用户体验,那么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)
        {
            
        }
    }
    

 

ContractedBlock.gif ExpandedBlockStart.gif 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);
    });

}

 

ContractedBlock.gif ExpandedBlockStart.gif 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 ; }
    }

 

ContractedBlock.gif ExpandedBlockStart.gif 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  %> &nbsp;&nbsp; 年龄: <% = ps.Age  %> </ li >
            
<% %>
        
</ ul >


 

  源码下载

 

原文地址:http://www.cnblogs.com/xumingxiang/archive/2010/05/04/1727614.html

作者 : 祥叔
出处: http://xumingxiang.cnblogs.com/
版权:本文版权归作者和博客园共有
转载:欢迎转载,为了保存作者的创作热情,请按要求【转载】,谢谢
要求:未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任

 

 
Tag标签: Asp.Net, jQuery
u60652.jpg
祥叔
关注 - 0
粉丝 - 1
关注博主

转载于:https://www.cnblogs.com/yurukai/archive/2010/05/06/1729187.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值