Asp.net Ajax框架教程

AJAX 专栏收录该内容
4 篇文章 0 订阅
目录
(一).概述...
(二).应用场景代码示例...
1).ScriptManager控件示例...
     1. 在异步调用服务端注册客户端脚本新方法...
     2. 捕获Ajax异步调用中错误(默认使用alert提示).
     3. 捕获Ajax异步调用中错误(自定义输出错误方式)
2).UpdatePanel控件示例...
     4. RenderMode属性用法示例...
     5. UpdateMode用法示例...
     6. ChildrenAsTriggers属性用法示例...
     7. Triggers属性用法示例...
3). UpdateProgress控件示例...
     8. 在异步更新时显示滚动进度条...
4). Timer控件示例...
     9.在客户端无刷新定时执行服务端方法...
5). Ajax中新Validators控件用法示例...
     10. Validators控件使用配置示例...
6). 在客户端请求服务端最基本的执行方式...
     11. 使用Ajax library类库中的客户端WebReqest对象请求服务端...
7). 在客户端调用页面后台(Page behind)中方法...
     12. 在客户端调用页面后台(Page behind)中方法示例...
8). 在客户端调用WebService中的服务端方法...
     13. 调用WebService示例...
9). 错误回调处理...
     14. 掌握客户端错误回调处理方法...
10). Ajax library客户端编程特性...
     15. Asp.net Ajax框架中的客户端对象与服务端对象交互...
     16.DataSet/DataTable/DataRow正反序列化JSON格式程序集使用...
     17. 客户端类使用Sys.StringBuilder使用示例...
     18. WebRequestManager对象的客户端事件示例...
11). 在Ajax操作中访问 Session-Cache-Application 对象...
     19. 在WebService方法中使用Session/Cache/Application对象...
     20. 在Page后台方法中使用Session/Cache/Application对象...
12). Ajax 客户端类库对现有 javascript对象的扩展功能...
     21. 扩展Array对象方法forEach使用示例...
     22. 对 JavaScript Function对象扩展, 注册事件新方式...
     23. Ajax对String对象扩展方法String.format的使用...
13). 在Ajax library中的客户端面向对象(OO)功能...
     24. 客户端注册命名空间, 定义接口, 类继承示例...
14). Asp.net Ajax 中的多语功能...
     25. Asp.net服务端使用全局和本地资源文件示例...
     26. Asp.net客户端使用全局和本地资源文件示例...
 
 
业余时间学习了一下微软的 Asp.net Ajax框架教程, 在学习时顺便整理了一个教程. 此教程包括26个精简的小例子, 主要针对开发应用场景和功能点进行展开示例, 在实际开发中也可以作为查找手册使用. 注释都在每个示例中.
Asp.net Ajax客户端对 Ajax编程支持非常丰富, 因此使用起来比较灵活.      --ChengKing(ZhengJian)
( 二).应用场景代码示例
1).ScriptManager 控件示例
1. 在异步调用服务端注册客户端脚本新方法
前台页面代码:
< body >
    <form id="form1" runat="server">
    <div>
        <!-- 注释 -->
        <!-- 在服务端注册客户端脚本新方法 -->        
        <!-- 通过Page.ClientScript实例注册客户端脚本方法在异步提交时不起作用. Microsoft采用ScriptManager实例, 并与Page.ClientScript方法一一对应的方法来实现此功能, 具体看示例后台代码. -->              
        <asp:ScriptManager ID="ScriptManager1" runat="server">
         </asp:ScriptManager>
         <asp:UpdatePanel ID="UpdatePanel1" runat="server">
              <ContentTemplate>
                   当前时间: <%= DateTime.Now %>
                   <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click1" />
              </ContentTemplate>
         </asp:UpdatePanel>         
    </div>
    </form>
</ body >
 
后台服务端代码:
public partial class _AA_ScriptManager_RegistClientScript_Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
 
    }
    protected void Button1_Click1(object sender, EventArgs e)
    {
        //Ajax 框架中新调用方式
        ScriptManager.RegisterStartupScript(this.UpdatePanel1, this.GetType(), "UpdateSucceed", "alert('Update time succeed!')", true);       
 
        // 默认调用方式(在异步调用XmlHttp方式中无效)
        //Page.ClientScript.RegisterStartupScript(this.GetType(), "UpdateSucceed", "<script>alert('Update time succeed!')</script>");
    }
}
2. 捕获Ajax异步调用中错误(默认使用alert提示)
前台页面代码:
< body >
    <form id="form1" runat="server">
    <div>
     
        <!-- 注释 -->
        <!-- 在Asp.net Ajax框架的异步调用中, 默认情况下不会直接拋出错误详细信息. 可以借助ScriptManager的OnAsyncPostBackError事件来实现 -->                
        <!-- AllowCustomErrorsRedirect="false" 表示遇到错误不跳转到Web.Config中定义的错误处理页面
            <system.web>
                <customErrors mode="On" defaultRedirect="~/DisplayError.aspx"></customErrors>
             </system.web>
             如果设置为true, 则出错时会自动将页面跳转到当前站点根目录下面的DisplayError.aspx页面.
         -->
        <asp:ScriptManager ID="ScriptManager1" runat="server" AllowCustomErrorsRedirect="false" OnAsyncPostBackError="ScriptManager1_AsyncPostBackError">
         </asp:ScriptManager>
         <asp:UpdatePanel ID="UpdatePanel1" runat="server">
              <ContentTemplate>
                   <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
              </ContentTemplate>
         </asp:UpdatePanel>    
        
    </div>
    </form>
</ body >
 
后台页面代码:
public partial class _AA_ScriptManager_GetAsycError_Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
 
    }
    protected void Button1_Click(object sender, EventArgs e)
    {       
        int a = 5, b = 0;
        int c = a / b;
    }
    protected void ScriptManager1_AsyncPostBackError(object sender, AsyncPostBackErrorEventArgs e)
    {
        ScriptManager.GetCurrent(this).AsyncPostBackErrorMessage = e.Exception.Message;
    }
}
3. 捕获Ajax异步调用中错误(自定义输出错误方式)
前台页面代码:
< body >
    <form id="form1" runat="server">
    <div>
        <!-- 注释 -->
        <!-- 在Asp.net Ajax框架的异步调用中, 默认情况下不会直接拋出错误详细信息. 可以借助ScriptManager的OnAsyncPostBackError事件来实现 -->                
        <!-- AllowCustomErrorsRedirect="false" 表示遇到错误不跳转到Web.Config中定义的错误处理页面
            <system.web>
                <customErrors mode="On" defaultRedirect="~/DisplayError.aspx"></customErrors>
             </system.web>
             如果设置为true, 则出错时会自动将页面跳转到当前站点根目录下面的DisplayError.aspx页面.
        -->
        <!-- 注意add_endRequest方法不能写到<head></head>中, 因为这时ScriptManager实例还没有创建. 不好之处是方法写在<head></head>块中使页面有些乱.-->         
     
        <asp:ScriptManager ID="ScriptManager1" runat="server" AllowCustomErrorsRedirect="false">
         </asp:ScriptManager>
         <asp:UpdatePanel ID="UpdatePanel1" runat="server">
              <ContentTemplate>
                   <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
              </ContentTemplate>
         </asp:UpdatePanel>
        
         <div id="divMessage" style="color:Red;"></div>
         <script type="text/javascript" language="javascript">
              Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function(sender, e)
              {
                   e.set_errorHandled(true); // 表示自定义显示错误, 将默认的alert提示禁止掉.
                   $get("divMessage").innerHTML = e.get_error().message;                
              });
         </script>
    </div>
</ form >
</ body >
 
后台服务端代码:
public partial class _AA_ScriptManager_GetAsycDetailError_CustomDisplayError_Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
 
    }
    protected void Button1_Click(object sender, EventArgs e)
    {
        int a = 5, b = 0;
        int c = a / b;
    }
}
2).UpdatePanel 控件示例
4. RenderMode 属性用法示例
< body >
    <form id="form1" runat="server">
    <div>
        <!-- 注释 -->
        <!-- RenderMode 属性功能与Html标签的style.display属性作用一样, 只是UpdatePanel只有Block和Inline两种方式 -->
   
        <asp:ScriptManager ID="ScriptManager1" runat="server">
         </asp:ScriptManager>
   
         <asp:UpdatePanel ID="UpdatePanel1" runat="server" RenderMode="Block">
              <ContentTemplate>
                   UpdatePanel1(Display 设置为Block)
              </ContentTemplate>
         </asp:UpdatePanel>
         <asp:UpdatePanel ID="UpdatePanel2" runat="server" RenderMode="Block">
              <ContentTemplate>
                   UpdatePanel2(Display 设置为Block)
              </ContentTemplate>
         </asp:UpdatePanel>
        
        
         <asp:UpdatePanel ID="UpdatePanel3" runat="server" RenderMode="Inline">
              <ContentTemplate>
                   UpdatePanel3(Display 设置为Inline)
              </ContentTemplate>
         </asp:UpdatePanel>    
         <asp:UpdatePanel ID="UpdatePanel4" runat="server" RenderMode=Inline>
              <ContentTemplate>
                   UpdatePanel4(Display 设置为Inline)
              </ContentTemplate>
         </asp:UpdatePanel>    
    </div>
</ form >
</ body >
5. UpdateMode 用法示例
< body >
    <form id="form1" runat="server">
    <div>
        <!-- 注释 -->
        <!-- UpdateMode 属性可以设置为Always和Conditional两种方式. 默认情况下属性值为Always. -->        
        <!-- 如果设置为Conditional, 则只有当前UpatePanel内部的元素(比如button)提交时, 才能引起当前UpdatePanel更新;-->
        <!-- 如果设置为Always, 则不管点击UpdatePanel内部还是外部的按钮都会使当前UpdatePanel更新 -->
       
        <asp:ScriptManager ID="ScriptManager1" runat="server">
         </asp:ScriptManager>
         <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode=always>
              <ContentTemplate>
                   UpdatePanel1 时间:<%= DateTime.Now %>
                   <asp:Button ID="Button1" runat="server" Text="Button" />
              </ContentTemplate>
         </asp:UpdatePanel>    
        
         <asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode=conditional>
              <ContentTemplate>
                   UpdatePanel2 时间:<%= DateTime.Now %>
                   <asp:Button ID="Button2" runat="server" Text="Button" />
              </ContentTemplate>
         </asp:UpdatePanel>
         <br />
        
    </div>
</ form >
</ body >
6. ChildrenAsTriggers 属性用法示例
< body >
    <form id="form1" runat="server">
    <div>
        <!-- 注释 -->
        <!-- ChildrenAsTriggers 属性可以设置为True或False. 默认情况下属性值为True. -->        
        <!-- 如果设置为False, 则点击当前UpdatePanel中的元素不会引起当前UpdatePanel更新;但它可能会引起本UpdatePanel之外的页面局部更新. -->        
       
        <asp:ScriptManager ID="ScriptManager1" runat="server">
         </asp:ScriptManager>
         <asp:UpdatePanel ID="UpdatePanel1" runat="server">
              <ContentTemplate>
                   UpdatePanel1 时间: <%= DateTime.Now %>
              </ContentTemplate>
         </asp:UpdatePanel>
         <asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode=conditional ChildrenAsTriggers="false">
              <ContentTemplate>
                   UpdatePanel2 时间: <%= DateTime.Now %>
                   <asp:Button ID="Button1" runat="server" Text="Button" />
              </ContentTemplate>
         </asp:UpdatePanel>
 
    </div>
    </form>
</ body >
7. Triggers 属性用法示例
< body >
    <form id="form1" runat="server">
    <div>
        <!-- 注释 -->
        <!-- PostBackTrigger(AsyncPostBackTrigger) 标记可以指定当前UpdatePanel之外的元素来对自己进行更新.不同:一个是一般页面提交, 一个是异步无刷新提交 -->        
        <!-- 假如设置了UpdateMode="Conditional", 则只有点击当前UpdatePanel中的button才能更新本Panel中的内容. 如果想设置本UpdatePanel外的元素对本Panel内容进行更新, 则可以设置该属性. -->      
        <asp:ScriptManager ID="ScriptManager1" runat="server">
         </asp:ScriptManager>
         <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
              <ContentTemplate>
                   当前时间: <%= DateTime.Now %>
                   <asp:Button ID="Button1" runat="server" Text="Button" />
              </ContentTemplate>
              <Triggers>            
                   <asp:PostBackTrigger ControlID="Button2" />                 
                   <asp:AsyncPostBackTrigger ControlID="Button3" />
              </Triggers>           
         </asp:UpdatePanel>
        
         <asp:UpdatePanel ID="UpdatePanel2" runat="server">
              <ContentTemplate>               
                   <asp:Button ID="Button2" runat="server" Text="Button" />
              </ContentTemplate>
         </asp:UpdatePanel>   
         <asp:UpdatePanel ID="UpdatePanel3" runat="server">
              <ContentTemplate>               
                   <asp:Button ID="Button3" runat="server" Text="Button" />
              </ContentTemplate>
         </asp:UpdatePanel>   
    </div>
    </form>
</ body >
3). UpdateProgress 控件示例
8. 在异步更新时显示滚动进度条
< body >
    <form id="form1" runat="server">
    <div>
        <!-- 注释 -->
        <!-- UpdateProgress 控件 -->        
        <!-- AssociatedUpdatePanelID 表示由哪个UpdatePanel来使自己呈现; -->      
        <!-- DynamicLayout 表示UpdateProgress是否固定占有一定空间,即使是隐藏时; 如果该值为true, 则只有显示时才占用页面空间. -->      
        <!-- DisplayAfter 表示显示UpdateProgress内容之前需要等待的时间. -->      
      
        <asp:ScriptManager ID="ScriptManager1" runat="server">
         </asp:ScriptManager>
 
         <asp:UpdateProgress ID="UpdateProgress1" runat="server" DynamicLayout=false AssociatedUpdatePanelID="UpdatePanel1" DisplayAfter="1000">
              <ProgressTemplate>
                <asp:Image ID="Image1" runat="server" ImageUr="~/(C)UpdateProgress/(8)UpdateProgress/Progress.gif" ImageUrl="~/(C)UpdateProgress/(8)UpdateProgress/Progress.gif" />
              </ProgressTemplate>
         </asp:UpdateProgress>
 
 
         <asp:UpdatePanel ID="UpdatePanel1" runat="server">
              <ContentTemplate>
                   当前时间: <%= DateTime.Now %>
                   <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
              </ContentTemplate>
         </asp:UpdatePanel>   
    </div>
    </form>
</ body >
4). Timer 控件示例
9. 在客户端无刷新定时执行服务端方法
< body >
    <form id="form1" runat="server">
    <div>
   
        <!-- 注释 -->
        <!-- Timer 控件 -->        
        <!-- 通过设置Interval值(毫秒)可以定期的更新页面; 可以配合UpdateMode来禁止某些UpdataPanle不更新. -->      
        <!-- 如果把Timer置于UpdatePanel外面, 可以非异步提交整个页面. -->              
       
        <asp:ScriptManager ID="ScriptManager1" runat="server">
         </asp:ScriptManager>
         <asp:UpdatePanel ID="UpdatePanel1" runat="server">
              <ContentTemplate>
                   当前时间: <%= DateTime.Now %>
                   <asp:Timer ID="Timer1" runat="server" Interval="1000">
                   </asp:Timer>
              </ContentTemplate>
         </asp:UpdatePanel>
         <%--<asp:Timer ID="Timer1" runat="server" Interval="1000">
    </asp:Timer>-- %>
    <%--<asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode=conditional>
              <ContentTemplate>
                   当前时间: <%= DateTime.Now %>                 
              </ContentTemplate>
         </asp:UpdatePanel>-- %>
    </div>
    </form>
</ body >
5). Ajax 中新Validators控件用法示例
使用VS 2005默认的验证控件在异步操作时会有些问题, 微软推出与现有控件名称一一对应的一系列验证控件
10. Validators 控件使用配置示例
< body >
    <form id="form1" runat="server">
    <div>
       
        <!-- 注释 -->
        <!-- Validators 控件 -->        
        <!-- Asp.net Ajax 与VS 2005自带的系列验证控件在使用时,会有些问题.固Microsoft又推出一系列与原控件名称一一对应的控件集, 在bin目录的Validators.dll -->      
        <!-- 另外, 还要在Web.Config中指定使用bin下面的Validators.dll中的验证控件:
            <system.web>
                <pages>                 
                    <tagMapping>
                          <add tagType="System.Web.UI.WebControls.CompareValidator" mappedTagType="Microsoft.Web.UI.Compatibility.CompareValidator, Validators"/>
                          <add tagType="System.Web.UI.WebControls.CustomValidator" mappedTagType="Microsoft.Web.UI.Compatibility.CustomValidator, Validators"/>
                          <add tagType="System.Web.UI.WebControls.RangeValidator" mappedTagType="Microsoft.Web.UI.Compatibility.RangeValidator, Validators"/>
                          <add tagType="System.Web.UI.WebControls.RegularExpressionValidator" mappedTagType="Microsoft.Web.UI.Compatibility.RegularExpressionValidator, Validators"/>
                          <add tagType="System.Web.UI.WebControls.RequiredFieldValidator" mappedTagType="Microsoft.Web.UI.Compatibility.RequiredFieldValidator, Validators"/>
                          <add tagType="System.Web.UI.WebControls.ValidationSummary" mappedTagType="Microsoft.Web.UI.Compatibility.ValidationSummary, Validators"/>
                     </tagMapping>
                </pages>
            </system.web>   
         -->     
       
        <asp:ScriptManager ID="ScriptManager1" runat="server">
         </asp:ScriptManager>
         <asp:UpdatePanel ID="UpdatePanel1" runat="server">
              <ContentTemplate>
                   <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
                   <asp:RequiredFieldValidator ControlToValidate="TextBox1" ID="RequiredFieldValidator1" runat="server" ErrorMessage=" 不能为NULL!"></ asp : RequiredFieldValidator >                
                   <br />
                   <asp:Button ID="Button1" runat="server" Text="Button" />
              </ContentTemplate>
         </asp:UpdatePanel>   
    </div>
    </form>
</ body >
6). 在客户端请求服务端最基本的执行方式
11. 使用Ajax library类库中的客户端WebReqest对象请求服务端
前台页面代码:
< body >
    <form id="form1" runat="server">
   
        <!-- 注释 -->
        <!-- 使用客户端WebRequest类, 进行一个标准的Ajax请求示例 -->      
       
        <asp:ScriptManager ID="ScriptManager1" runat="server">
         </asp:ScriptManager>
        
         <script language="jscript" type="text/javascript">
              function ExecuteAjaxRequest(text)
              {
                   var request = new Sys.Net.WebRequest();
                   request.set_url('ClientWebRequest.ashx');
                   request.set_httpVerb("POST");
                   request.add_completed(onComplete);
                                
                      
                   request.set_body('text=' + encodeURIComponent(text));                
                   request.invoke();
              }
             
              function onComplete(response)
              {
                   if (response.get_responseAvailable())
                   {
                       var text = response.get_object();
                       alert(text);
                   }
              }
         </script>
        
         <input type="button" value="Hello Word!" onclick="ExecuteAjaxRequest('Hello Word!')" />      
</ form >
</ body >
 
处理程序ashx文件代码:
using System;
using System.Web;
 
using System.Web.Script.Serialization;
 
public class ClientWebRequest : IHttpHandler {
   
    public void ProcessRequest (HttpContext context) {
       
        context.Response.ContentType = "text/plain";      
        string text = context.Request.Params["text"];       
 
        JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
 
        context.Response.Write(jsSerializer.Serialize(text));
    }
 
    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
 
}
7). 在客户端调用页面后台(Page behind)中方法
12. 在客户端调用页面后台(Page behind)中方法示例
前台页面代码:
< body >
    <form id="form1" runat="server">
    <div>
       
        <!-- 注释 -->
        <!-- 在开发中使用较多的情况, 在客户端调用当前页面的服务端方法. -->                
        <!-- 设置ScriptManager控件的EnablePageMethods属性为:True, 并且在需要使用后台方法前加属性标记[WebMethod] -->
        <!-- 服务端方法必须为静态的, 需要客户端调用的才需要设置为静态的; -->
        <!-- 注意在服务端类中要打开命名空间using System.Web.Services, WebMethod类在此命名空间中-->
             
         <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true" />
        
         <input type="button" value=" 调用服务端方法" onclick="ExecuteServerMethod('ChengKing')" />
   
         <script language="javascript" type="text/javascript">
              function ExecuteServerMethod(value)
              {
                   PageMethods.ReturnStringServerMethod(value,CallBackResult);
              }
             
              function CallBackResult(result)
              {
                   alert(result);
              }
         </script>
        
    </div>
    </form>
</ body >
页面后台服务端代码:
using System.Web.Services;
public partial class _G_Ajax_Visit_PageServer_Method_Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
    }
    [WebMethod]
    public static string ReturnStringServerMethod(string str)
    {       
        return "Hello " + str;
}
}
8). 在客户端调用WebService中的服务端方法
13. 调用WebService示例
前台页面代码:
< body >
    <form id="form1" runat="server">
    <div>
   
        <!-- 注释 -->
        <!-- 如果WebService类代码在App_Code中, 则直接可以通过: 类名.方法调用; 否则, 要通过: 命名空间.类名.方法名称 调用. -->        
        <!-- InlineScript=true 表示在客户端把调用服务端生成的客户端代码脚本输出到页面上; 一般用于调试使用, 但肯定占用时间. -->
        
        <asp:ScriptManager ID="ScriptManager1" runat="server">
            <Services>
                <asp:ServiceReference Path="SimpleTransferWebservice.asmx" InlineScript=false />
            </Services>
        </asp:ScriptManager>
        <script language="javascript" type="text/javascript">
              function showEmployee(str)
              {
                   SimpleTransferWebservice.HelloWorld(              
                       str,
                       onCompleted);
              }            
              function onCompleted(response)
              {
                   alert(response);
              }
         </script>
        
         <input type="button" value="Hello Word!"
              onclick="showEmployee(this.value)" />
    </div>
</ form >
</ body >
 
Webservice 后台代码(*.asmx页面):
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class SimpleTransferWebservice : System.Web.Services.WebService {
 
    public SimpleTransferWebservice () {
 
        // 如果使用设计的组件,请取消注释以下行
        //InitializeComponent();
    }
 
    [WebMethod]
    [ScriptMethod]
    public string HelloWorld
        (string str) {
        return str;
    }   
}
9). 错误回调处理
14. 掌握客户端错误回调处理方法
前台页面代码:
< body >
    <form id="form1" runat="server">
    <div>
   
        <!-- 注释 -->
        <!-- 使用页面后台服务端方法则要把属性EnablePageMethods设置为True; -->
        <!-- 本客户端处理错误方式, 以及设置属性(set_timeout或Timeout), 同样应用于WebService方法也是可以的 -->
             
        <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods=true>            
         </asp:ScriptManager>
        
         <input type="button" value=" 一般错误异常" onclick="Division(1, 0)" />
         <input type="button" value=" 超时异常" onclick="Timeout()" />
        
         <script language="javascript" type="text/javascript">
              function Division(a, b)
              {
                   PageMethods.Division(a, b, null, ErrorCallback);
              }
             
              function Timeout()
              {
                   PageMethods.set_timeout(1000);
                   PageMethods.Timeout(null, ErrorCallback);
              }
             
              function ErrorCallback(e)
              {
                   var OupPutMessage = String.format(" 是否超时: {0}/n错误信息: {1}/n异常类型: {2}/n堆栈跟踪: {3}" ,e.get_timedOut(),e.get_message(),e.get_exceptionType(),e.get_stackTrace());        
                   alert(OupPutMessage);
              }
         </script>   
    </div>
</ form >
</ body >
 
后台服务端代码:
using System.Threading;
using System.Web.Services;
 
public partial class _I_FailedCallback_Process_Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
    }
    [WebMethod]
    public static int Division(int a,int b)
    {
        return a/b;
    }
    [WebMethod]
    public static void Timeout()
    {
        Thread.Sleep(2000); // 超时情况       
    }
}
10). Ajax library 客户端编程特性
15. Asp.net Ajax 框架中的客户端对象与服务端对象交互
前台页面代码:
< body >
    <form id="form1" runat="server">
    <div>
   
        <!-- 注释 -->
        <!-- Asp.net Ajax 框架中的客户端对象与服务端对象交互; Ajax框架还支持强类型集合,具体请看示例代码. -->
        <!-- 使用页面后台服务端方法则要把属性EnablePageMethods设置为True; -->        
             
        <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods=true>            
         </asp:ScriptManager>       
         <input type="button" value=" 客户端对象传递到服务端" onclick="Add1000Salary()" />       
         <input type="button" value=" 服务端对象传递到客户端" onclick="GetServerObject()" />     
         <script language="javascript" type="text/javascript">
              function Add1000Salary()
              {   
                  // 如果Person不在App_Code中, 则使用方式如:var person = new 命名空间.Person();          
                   var person = new Person(); //or var person = new Object();
                  
                   person.Name = "Rose Zhao";
                   person.Sex = "Female";
                   person.Salary = 2000;               
                   PageMethods.Add_1000_Salary(person, Add_1000_SalarySucceeded);
              }            
              function Add_1000_SalarySucceeded(result)
              {
                   var message = String.format(" 姓名: {0}; 性别: {1}; 工资: {2}" ,result.Name, result.Sex, result.Salary);                   
                   alert(message);
              }                 
             
              function GetServerObject()
              {
                   PageMethods.GetOnePerson(GetServerObjectSucceeded);
              }            
              function GetServerObjectSucceeded(result)
              {
                   for (var key in result)
                   {                     
                       var message = String.format(
                       " 姓名: {0}; 性别: {1}; 工资: {2}" ,result[key].Name, result[key].Sex, result[key].Salary);                     
                       alert(message);
                   }
              }
             
        </script>
    </div>
</ form >
</ body >
 
后台服务端代码:
using System.Web.Services;
using System.Collections.Generic;
public partial class _J_Use_ClientObject_in_Ajax_Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {      
    }
    [WebMethod]
    public static Person Add_1000_Salary(Person person)
    {
        person.Salary += 1000;
        return person;
    }
    [WebMethod]
    public static IDictionary<string, Person> GetOnePerson()
    {
        Dictionary<string, Person> result = new Dictionary<string, Person>();
        Person person = new Person();
        person.Name = "Rose Zhao";
        person.Sex = "Female";
        person.Salary = 2000;
        result[person.Name] = person;
        return result;
    }
}
 
16.DataSet/DataTable/DataRow 正反序列化JSON格式程序集使用
前台页面代码:
< body >
    <form id="form1" runat="server">
    <div>
   
        <!-- 注释 -->
        <!-- Microsoft.Web.Preview Serializer 是ASP.NET AJAX January Futures CTP 中包括的一个程序集, 含有DatSet/DataTable/DataRow这些循环引用对象的序列化类, 使用时只要将
            Microsoft.Web.Preview.dll 添加到bin目录下面, 再在Web.config中这样配置:
            <system.web.extensions>
                 <scripting>
                      <webServices>           
                        <jsonSerialization>
                          <converters>
                            <add name="DataSetConverter" type="Microsoft.Web.Preview.Script.Serialization.Converters.DataSetConverter, Microsoft.Web.Preview" />
                            <add name="DataRowConverter" type="Microsoft.Web.Preview.Script.Serialization.Converters.DataRowConverter, Microsoft.Web.Preview" />
                            <add name="DataTableConverter" type="Microsoft.Web.Preview.Script.Serialization.Converters.DataTableConverter, Microsoft.Web.Preview" />           
                          </converters>
                        </jsonSerialization>       
                      </webServices>
                  <scripting>   
       </system.web.extensions>       
         -->
        <!-- 具体用法请看本示例 -->     
       
        <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods=true>            
         </asp:ScriptManager>       
         <input type="button" value=" 获取数据" onclick="GetPersonDataTable();" />                         
         <script language="javascript" type="text/javascript">
              function GetPersonDataTable()
              {
                   PageMethods.GetPersonDataTable(CallBackProcessResultMethod,ErrorHandler);
              }
             
              function CallBackProcessResultMethod(result)
              {           
                   var sb = new Sys.StringBuilder("<table border='1' bgcolor='#6699ff'>");
                   sb.append("<tr><td> 姓名</td><td>性别</td><td>工资</td></tr>" );
                   for (var i = 0; i < result.rows.length; i++)
                   {
                        sb.append(String.format("<tr><td>{0}</td><td>{1}</td><td>{2}</td></tr>",result.rows[i]["Name"],result.rows[i].Sex, result.rows[i].Salary));
                   }
                   sb.append("</table>");              
                   $get("table").innerHTML = sb.toString();
              }   
             
              function ErrorHandler(error)
              {
                   alert(error.get_message());
              }            
         </script>    
         <br />
         <div id="table"></div>
    </div>
</ form >
</ body >
 
后台页面代码:
using System.Web.Services;
using System.Web.Script.Serialization;
public partial class _J_Ajax_Client_Programe__B_JS_StringBuilder_Class_Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
    }
    [WebMethod]       
    public static DataTable GetPersonDataTable()
    {
        //return "abc";
        DataTable dt = new DataTable();
        dt.Columns.Add(new DataColumn("Name", typeof(string)));
        dt.Columns.Add(new DataColumn("Sex", typeof(string)));
        dt.Columns.Add(new DataColumn("Salary", typeof(string)));
 
        DataRow drNew = dt.NewRow();
        drNew["Name"] = "Rose Zhao";
        drNew["Sex"] = "Female";
        drNew["Salary"] = "2000";
        dt.Rows.Add(drNew);
 
        drNew = dt.NewRow();
        drNew["Name"] = "King Zheng";
        drNew["Sex"] = "male";
        drNew["Salary"] = "3000";
        dt.Rows.Add(drNew);      
 
        return dt;
    }
}
17. 客户端类使用Sys.StringBuilder使用示例
前台页面代码
< body >
    <form id="form1" runat="server">
    <div>
   
        <!-- 注释 -->
        <!-- .Sys.StringBuilder 类在IE下可以提交客户端程序运行效率, 与服务端的System.Text.StringBuilder功能相同, 只不过分别用于客户端和服务端 -->        
       
        <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods=true>            
         </asp:ScriptManager>       
         <input type="button" value=" 获取数据" onclick="GetPersonDataTable();" />                         
         <script language="javascript" type="text/javascript">
              function GetPersonDataTable()
              {
                   PageMethods.GetPersonDataTable(CallBackProcessResultMethod,ErrorHandler);
              }
             
              function CallBackProcessResultMethod(result)
              {           
                   var sb = new Sys.StringBuilder("<table border='1' bgcolor='#6699ff'>");
                   sb.append("<tr><td> 姓名</td><td>性别</td><td>工资</td></tr>" );
                   for (var i = 0; i < result.rows.length; i++)
                   {
                        sb.append(String.format("<tr><td>{0}</td><td>{1}</td><td>{2}</td></tr>",result.rows[i]["Name"],result.rows[i].Sex, result.rows[i].Salary));
                   }
                   sb.append("</table>");              
                   $get("table").innerHTML = sb.toString();
              }   
             
              function ErrorHandler(error)
              {
                   alert(error.get_message());
              }            
         </script>    
         <br />
         <div id="table"></div>
    </div>
    </form>
</ body >
后台页面代码:
using System.Web.Services;
using System.Web.Script.Serialization;
 
public partial class _J_Ajax_Client_Programe__B_JS_StringBuilder_Class_Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
 
    }
 
    [WebMethod]   
    public static DataTable GetPersonDataTable()
    {
        //return "abc";
        DataTable dt = new DataTable();
        dt.Columns.Add(new DataColumn("Name", typeof(string)));
        dt.Columns.Add(new DataColumn("Sex", typeof(string)));
        dt.Columns.Add(new DataColumn("Salary", typeof(string)));
 
        DataRow drNew = dt.NewRow();
        drNew["Name"] = "Rose Zhao";
        drNew["Sex"] = "Female";
        drNew["Salary"] = "2000";
        dt.Rows.Add(drNew);
 
        drNew = dt.NewRow();
        drNew["Name"] = "King Zheng";
        drNew["Sex"] = "male";
        drNew["Salary"] = "3000";
        dt.Rows.Add(drNew);      
 
        return dt;
    }
}
18. WebRequestManager 对象的客户端事件示例
< body >
    <form id="form1" runat="server">
    <div>
   
    <!-- 注释 -->
    <!-- Ajax library 中的客户端类Sys.Net.WebRequestManager事件丰富, 具体请看示例 -->  
    <!-- 通过该类注册的事件只能在XmlHttp异步更新操作时, 才能够捕捉到. -->
   
    <script language="javascript">
              Sys.Net.WebRequestManager.add_invokingRequest(function(sender, eventArgs)
              {
                   if (confirm(" 是否取消本操作?" ))
                   {
                       eventArgs.set_cancel(true);                   
                   }
              });          
              Sys.Net.WebRequestManager.add_completedRequest(function()
              {
                   alert(" 刷新时间操作成功!" );
              });
         </script>
        
        <asp:ScriptManager ID="ScriptManager1" runat="server" />     
         <asp:UpdatePanel ID="UpdatePanel1" runat="server">
              <ContentTemplate>
                   <asp:Button ID="Button1" runat="server" Text=" 更新当前时间[无刷新]" />
                   <br /><br />
                   当前时间: <%= DateTime.Now.ToString() %>               
              </ContentTemplate>
         </asp:UpdatePanel>
        
         <asp:Button ID="Button2" runat="server" Text=" 更新当前时间[刷新]" />
    </div>
    </form>
</ body >
11). 在Ajax操作中访问 Session-Cache-Application 对象
19. 在WebService方法中使用Session/Cache/Application对象
前台页面代码:
< body >
    <form id="form1" runat="server">
    <div>
   
        <!-- 注释 -->
        <!-- 在WebService方法中使用Session/Cache/Application对象 -->        
               
        <asp:ScriptManager runat="server" ID="ScriptManager1">            
            <Services>
                   <asp:ServiceReference Path="UseSession_etc.asmx" InlineScript="true" />
              </Services>
         </asp:ScriptManager>   
        
         <input type="button" value=" 改变服务端Session中存储的值" onclick="ChangeSession()" />
         <input type="button" value=" 改变服务端Cache中存储的值" onclick="ChangeCache()" />
         <input type="button" value=" 改变服务端Application中存储的值" onclick="ChangeApplication()" />
    
         <script language="javascript" type="text/javascript">
              function ChangeSession()
              {
                   UseSession_etc.ChangeSession(ChangeSucceeded);
              }
              function ChangeCache()
              {
                   UseSession_etc.ChangeCache(ChangeSucceeded);
              }
              function ChangeApplication()
              {
                   UseSession_etc.ChangeApplication(ChangeSucceeded);
              }
             
              function ChangeSucceeded(result)
              {
                   alert(result);
              }
         </script>    
    </div>
</ form >
</ body >
 
WebService 页面后台代码(*.asmx) :
/// <summary>
/// UseSession_etc 的摘要说明
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class UseSession_etc : System.Web.Services.WebService {
 
    public UseSession_etc () {
 
        // 如果使用设计的组件,请取消注释以下行
        //InitializeComponent();     
    }
 
    [WebMethod(EnableSession=true)]
    public int ChangeSession()
    {
        if (Session["count"] == null)
        {
            Session["count"] = "0";
        }
 
        int intCount = int.Parse(Session["count"].ToString());
        intCount++;
        Session["count"] = intCount;
        return intCount;
    }
 
    [WebMethod]
    public int ChangeCache()
    {
        if (this.Context.Cache["count"] == null)
        {
            this.Context.Cache["count"] = "0";
        }
        int intCount = int.Parse(this.Context.Cache["count"].ToString());
        intCount++;
        this.Context.Cache["count"] = intCount;
        return intCount;
    }
 
    [WebMethod]
    public int ChangeApplication()
    {
        if (Application["count"] == null)
        {
            Application["count"] = "0";
        }
        int intCount = int.Parse(Application["count"].ToString());
        intCount++;
        Application["count"] = intCount;
        return intCount;
    }   
}
20. 在Page后台方法中使用Session/Cache/Application对象
前台页面代码:
< body >
    <form id="form1" runat="server">
    <div>
   
        <!-- 注释 -->
        <!-- 在Page后台方法中使用Session/Cache/Application对象 -->   
       
        <asp:ScriptManager runat="server" ID="ScriptManager1" EnablePageMethods=true>                        
         </asp:ScriptManager>   
        
         <input type="button" value=" 改变服务端Session中存储的值" onclick="ChangeSession()" />
         <input type="button" value=" 改变服务端Cache中存储的值" onclick="ChangeCache()" />
         <input type="button" value=" 改变服务端Application中存储的值" onclick="ChangeApplication()" />
    
         <script language="javascript" type="text/javascript">
              function ChangeSession()
              {
                   PageMethods.ChangeSession(ChangeSucceeded);
              }
              function ChangeCache()
              {
                   PageMethods.ChangeCache(ChangeSucceeded);
              }
              function ChangeApplication()
              {
                   PageMethods.ChangeApplication(ChangeSucceeded);
              }
             
              function ChangeSucceeded(result)
              {
                   alert(result);
              }
         </script>    
    </div>
</ form >
</ body >
 
页面后台代码
using System.Web.Services;
using System.Web.SessionState;
using System.Web.Caching;
public partial class _K_EnableSession_in_Ajax_Progam_Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        //Session["count"] = "0";
        //Cache["count"] = "0";
        //Application["count"] = "0";              
    }
 
    [WebMethod(EnableSession = true)]
    public static int ChangeSession()
    {
        if (System.Web.HttpContext.Current.Session["count"] == null)
        {
            System.Web.HttpContext.Current.Session["count"] = "0";
        }
 
        int intCount = int.Parse(System.Web.HttpContext.Current.Session["count"].ToString());
        intCount++;
        System.Web.HttpContext.Current.Session["count"] = intCount;
        return intCount;
    }
 
    [WebMethod]
    public static int ChangeCache()
    {
        if (System.Web.HttpContext.Current.Cache["count"] == null)
        {
            System.Web.HttpContext.Current.Cache["count"] = "0";
        }
        int intCount = int.Parse(System.Web.HttpContext.Current.Cache["count"].ToString());
        intCount++;
        System.Web.HttpContext.Current.Cache["count"] = intCount;
        return intCount;
    }
 
    [WebMethod]
    public static int ChangeApplication()
    {
        if (System.Web.HttpContext.Current.Application["count"] == null)
        {
            System.Web.HttpContext.Current.Application["count"] = "0";
        }
        int intCount = int.Parse(System.Web.HttpContext.Current.Application["count"].ToString());
        intCount++;
        System.Web.HttpContext.Current.Application["count"] = intCount;
        return intCount;
    }
}
 
12). Ajax 客户端类库对现有 javascript对象的扩展功能
21. 扩展Array对象方法forEach使用示例
< body >
    <form id="form1" runat="server">
    <div>
        
        <!-- 注释 -->
        <!-- Ajax Library 中对Array的扩展方法forEach的使用. -->      
       
        <asp:ScriptManager ID="ScriptManager1" runat="server" />   
         <script language="javascript" type="text/javascript">
                           
              var str = "Hello Rose Zhao".split(" ");
              var obj = {returnValue : ""};
              Array.forEach(str, tidy, obj);// 参数1: 要整理的字符串; 参数2: 委托的客户端方法名称; 参数3: 存放结果的对象.             
              alert(obj.returnValue);
             
              function tidy(elt, index, array)
              {
                   this.returnValue += "[" + elt + "] ";
              }
             
         </script>
    </div>
    </form>
</ body >
22. 对 JavaScript Function对象扩展, 注册事件新方式
< body >
    <form id="form1" runat="server">
    <div>
       
        <!-- 注释 -->
        <!-- 为Button1增加Click事件, 并调用自定义对象的自定义方法 -->   
       
        <asp:ScriptManager ID="ScriptManager1" runat="server" />     
         <input type="button" value=" 调用事件" id="button1" />       
         <script language="javascript" type="text/javascript">           
              var clientObject =
              {
                   text : "Hello ",   
                   OnClick : function(e, args)
                   {
                       alert(this.text + args + this.tail);
                   },
                   tail : "!"
              }            
              var onClickDelegate = Function.createCallback(Function.createDelegate(clientObject, clientObject.OnClick), "Rose Zhao");
              $addHandler($get("button1"), "click", onClickDelegate);
         </script>
    </div>
    </form>
</ body >
23. Ajax 对String对象扩展方法String.format的使用
< body >
    <form id="form1" runat="server">
    <div>
       
        <!-- 注释 -->
        <!-- String 扩展方法format和localeFormat的使用 -->   
       
        <asp:ScriptManager ID="ScriptManager1" runat="server" />              
         <script language="javascript" type="text/javascript">
             alert(String.format("Today is {0}.", new Date()));
              alert(String.localeFormat(" 今天是{0}" , new Date()));
         </script>
    </div>
    </form>
</ body >
13). 在Ajax library中的客户端面向对象(OO)功能
24. 客户端注册命名空间, 定义接口, 类继承示例
< body >
    <form id="form1" runat="server">
    <div>
   
        <!-- 注释 -->
        <!-- Ajax library 对客户端面向对象的支持 -->   
       
        <asp:ScriptManager ID="ScriptManager1" runat="server" ScriptMode="Debug">            
         </asp:ScriptManager>   
        
         <script language=javascript>
        
             // 注册一个命名空间: "人类"
             Type.registerNamespace("Human");
            
             // 定义一个接口: IPerson
             Human.IPerson = function()
            {
                 throw Error.notImplemented();
            }
            Human.IPerson.prototype =
            {
                 FullName : function()
                 {
                     throw Error.notImplemented();
                 }           
            }
            Human.IPerson.registerInterface("Human.IPerson");
           
            // 定义一个类: Womenn , 并继承Human.IPerson
            Human.Womenn = function()
            {
                 this._FirstName;
                 this._LastName;
            }
            Human.Womenn.prototype =
            {
                 get_FirstName : function()
                 {
                     return this._FirstName;
                 },
                 set_FirstName : function(value)
                 {
                     this._FirstName = value;
                 },
             
                 get_LastName : function()
                 {
                     return this._LastName;
                 },                            
                 set_LastName : function(value)
                 {
                     this._LastName = value;
                 },
             
                 FullName : function()
                 {
                     return this._FirstName + " " + this._LastName;
                 }
            }
            Human.Womenn.registerClass("Human.Womenn", null,Human.IPerson);           
           
            // 使用定义的类
            //debugger;
            var Rose = new Human.Womenn();           
            // 注意这里不是这样写:Rose.set_LastName = "Jing";
            Rose.set_FirstName("Jing");            
            Rose.set_LastName("Zhao");           
            alert(Rose.FullName());
           
         </script>
    </div>
    </form>
</ body >
14). Asp.net Ajax 中的多语功能
25. Asp.net 服务端使用全局和本地资源文件示例
前台页面代码:
< body >
    <form id="form1" runat="server">
   
    <!-- 注释 -->
    <!-- Asp.net 全局和本地资源文件示例. -->        
    <!-- UICulture: 设置本页面界面资源语种; Culture=设置本页面对象资源语种. 这里都设置为auto, 在实际运行时它会根据客户端浏览器设置的语言进行显示. -->    
    <!-- 全局资源文件是指供所有页面使用. 本地资源文件是指供一个特定页面使用, 其App_LocalResources文件夹必须和页面在同一级目录下面-->    
    <!-- 切换语言[中文<=>英文]看效果: 客户端设置浏览器的步骤: "工具"-"Internet选项"-"语言"; 如果没有 zh-cn或en-US, 将这两项加入, 加放后移到最上面的为默认启用.-->        
   
    <div>
        <!-- 获取全局资源文件 -->
        <asp:Label ID="lbApple" runat="server"></asp:Label>       
        <asp:Label ID="lbOrange" runat="server" Text="<%$ Resources:GlobalFruitsResource,Orange %>"></asp:Label>
       
        <!-- 获取本地资源文件 -->
        <asp:Label ID="lbBanana" runat="server" meta:resourcekey="lblBanana"></asp:Label>       
       
    </div>
    </form>
</ body >
后台页面代码:
public partial class _N_Global_and_Local_Resources__A_Asp_net_Resource_Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // 获取全局资源文件
        this.lbApple.Text = Resources.GlobalFruitsResource.Apple;
    }
}
 
26. Asp.net 客户端使用全局和本地资源文件示例
前台页面代码:
< body >
    <form id="form1" runat="server">
    <div>
   
        <!-- 注释 -->
        <!-- Ajax 对客户端资源文件的支持. -->        
        <!-- Ajax 中对客户端资源文件支持是通过定义多个*.js文件来实现的, 每个js文件实现一种语言所有的资源 -->  
        <!-- UICulture: 设置本页面界面资源语种; Culture=设置本页面对象资源语种. 这里都设置为auto, 在实际运行时它会根据客户端浏览器设置的语言进行显示. -->       
        <!-- 切换语言[中文<=>英文]看效果: 客户端设置浏览器的步骤: "工具"-"Internet选项"-"语言"; 如果没有 zh-cn或en-US, 将这两项加入, 加放后移到最上面的为默认启用.-->        
        <!-- 与服务端资源文件相比, 这里还要指定一个很重要的属性ResourceUICultures, 指定支持的客户端语言种类集合, 用逗号分开 -->
        <!-- 客户端命名的各个语言的JS文件, 比如: FruitsResource.en-US.js中的en-US, 必须为浏览器中可选择类型中的一种, 不能自已定义! -->
        <!--JS 文件中的: /// <reference name="MicrosoftAjax.js"/> 表示把此文件引用进来, 相当于C#语法中using指令, 只不过这里不是打开命名空间,而是引入文件 -->        
   
        <asp:ScriptManager runat="server" ID="sm" EnableScriptLocalization="true">
            <Scripts>
                <asp:ScriptReference Path="~/(N)Global and Local Resources/(26)Ajax Resource/FruitsResource.js" ResourceUICultures="zn-ch,en-US" />
            </Scripts>
        </asp:ScriptManager>
       
        <script language="javascript">
            alert(Fruits.Fruit.Pear);
        </script>
       
    </div>
    </form>
</ body >
 
中文资源文件FruitsResource.js代码:
/// <reference name="MicrosoftAjax.js"/>
Type.registerNamespace("Fruits");
 
Fruits.Fruit =
{
    "Pear" : " 梨"
}
 
英文资源文件FruitsResource.en-US.js代码:
/// <reference name="MicrosoftAjax.js"/>
Type.registerNamespace("Fruits");
 
Fruits.Fruit =
{
    "Pear" : "Pear"
}
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值