posts - 69, comments - 301, trackbacks - 21, articles - 0
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

2008年6月10日

ASP.NET 网站应用程序是无状态的,客户端每执行一次 PostBack 动作,所有的对象都需要重新建立;当然这样的执行模式相当没有效率,所以在 ASP.NET 应用程序中有 Application、Session、Cache 这三类资料暂存区。Application 的生命周期与应用程序相同,Session 的生命周期与个别使用者相同,而 Cache 的生命周期则由程序设计师自订,Cache 相对于 Application 及 Session 来说显示更有弹性。
选择合适的 Cache 方案能有效提升网站的执行效能,设定 Cache 过期的条件可分为下列三种。
1.绝对时间:插入对象过期并从快取移除的时间。
2.浮动时间:上次存取插入对象的时间与该对象到期的时间之间隔。如果这个数值等于二十分钟,那么对象将会在最后存取的二十分钟后过期并从快取中移除。
3.档案相依:项目的档案或快取索引键相依性。例如,假设您根据 XML 档案中的数据建立 DataSet 对象,您可以将 DataSet 加入含有 CacheDependency 对象的快取,该对象使 DataSet 相依于此 XML 档案。如果 XML 档案变更,则会从快取中移除 DataSet。
笔者常使用 Cache 来暂存经常存取的设定数据,一般作法是根据 XML 档案建立「设定类别」,这个类别再放入 Cache,并设定快取过期条件为「浮动时间+XML 档案相依」。这样的快取方案有二个优点。
1.该对象存取的频率愈多,则会优先置于 Cache,不易从 Cache 被移除。
2.当设定的 XML 档案内容变更时,Cache 则会被移除,以保持最新资料。
 
这个快取方案的算法如下
Step1:要求对象。
Step2:检查 Cache 中是否有该对象。
Step3:若 Cache 中有该对象,则取得对象跳离程序。反之则执行 Step4。
Step4:由 XML 档案建立对象,并存入 Cache,并传回该物件。
 
假设 TMySetting 对象要使用上述的快取方案,程序代码实作如下。程序代码中处理反序列化的 TBSerializerUtil.XmlFileToObject 方法 ,请参阅「物件序列化函式库」一文。

 

    ''' <summary>
    
''' 依键值取得 TMySetting 对象。
    
''' </summary>
    
''' <param name="Key">键值。</param>
    Public Function GetMySetting(ByVal Key As StringAs TMySeting
        
Dim sCacheKey As String
        
Dim oCache As System.Web.Caching.Cache
        
Dim oMySeting As TMySeting
        
Dim sFileName As String

        
'快取键值为「型别名称.键值」
        sCacheKey = String.Format("{0}.{1}"GetType(TMySeting).Name, Key)

        
'ASP.NET 快取物件
        oCache = System.Web.HttpContext.Current.Cache

        
If oCache(sCacheKey) IsNot Nothing Then
            
'直接由 Cache 取得该对象
            oMySeting = CType(oCache(sCacheKey), TMySeting)
        
Else
            
'由 XML 档案建立对象
            sFileName = "对象对应的文件名称"
            oMySeting 
= CType(TBSerializerUtil.XmlFileToObject(sFileName, GetType(TMySeting)), TMySeting)

            
'将对象存入 Cache,并设定快取移除时机
            '1.档案相依
            '2.浮动时间为 5 分钟
            oCache.Insert(sCacheKey, oMySeting, _
                          
New System.Web.Caching.CacheDependency(sFileName), _
                          System.Web.Caching.Cache.NoAbsoluteExpiration, 
New TimeSpan(050))
        
End If
        
Return oMySeting
    
End Function

 

后记:
在 EnterpriseLibrary 中也有处理快取的 CacheManager 对象,它类似 ASP.NET 的 Cache 物件。若是撰写三层式架构,也可以使用 EnterpriseLibrary 的 CacheManager 来取代 ASP.NET Cache,往后有时间再来介绍 EnterpriseLibrary 的 CacheManager 对象。

posted @ 2008-08-28 22:23 jeff377 阅读(200) | 评论 (0)编辑

利用 RegEx 可以很方便的做字符串处理,若我们需要从一篇文章中撷取出关键词片段(含前后文),可以利用下列的 FindKeywordParts 函式来处理,搜寻到的关键词片段的字符串集合会以 List(Of String) 型别传回。

 

    ''' <summary>
    
''' 由字符串中寻找关键词片段。
    
''' </summary>
    
''' <param name="Text">字符串。</param>
    
''' <param name="Keyword">关键词。</param>
    
''' <param name="BLength">包含关键词前的字符数。</param>
    
''' <param name="ALength">包含关键词后的字符数。</param>
    
''' <returns>传回符合的关键词片段的字符串集合。</returns>
    Public Shared Function FindKeywordParts( _
        
ByVal Text As String, _
        
ByVal Keyword As String, _
        
ByVal BLength As Integer, _
        
ByVal ALength As IntegerAs List(Of String)

        
Dim sPattern As String
        
Dim oRegEx As Regex
        
Dim oMatchs As MatchCollection
        
Dim oMatch As Match
        
Dim oList As New List(Of String)

        
'比对规则
        sPattern = String.Format(".{{0,{1}}}{0}.{{0,{2}}}", Keyword, BLength, ALength)
        oRegEx 
= New Regex(sPattern)

        oMatchs 
= oRegEx.Matches(Text)
        
For Each oMatch In oMatchs
            oList.Add(oMatch.Value)
        
Next
        
Return oList
    
End Function

 

假设我们要找一篇文章中,包含「连胡会」这个关键词片段,并包含关键词前后文各10个字符,程序代码如下

 

        Dim sText As String = "宋胡会可望谈两岸政治定位【吴燕玲╱台北报导】连胡会之后国民党单独召开记者会,以新闻公报的形式发布五大共识,亲民党中央昨天不愿对连胡会发表看法"
        
Dim oList As List(Of String)
        oList 
= FindKeywordParts(sText, "连胡会"1010)

 

 

posted @ 2008-08-27 19:22 jeff377 阅读(721) | 评论 (2)编辑

当设定 ScriptManager 控件的 EnablePageMethods 属性值为 True 时,我们可以从客户端指令码呼叫 ASP.NET 网页中的公用静态网页方法,而且它预设就支持 JSON 序列化。在本文中将使用 ScriptManager 的 PageMethods,重新做一次上篇「CallBack PageCommand 与 JSON 序列化」文章的范例,来比较「CallBack PageCommand」及 「ScriptManager PageMethods」之间的差异。
 
我们先来复习上篇范例 CallBack PageCommand 的运作流程如下


客户端物件 -> 1.客户端 JSON 序列化 -> CallBack 呼叫伺服端 -> 2.伺服服端 JSON 反序列化还原对象 -> 修改对象属性
-> 3.伺服端 JSON 序列化 -> CallBack 回传客户端 -> 4.客户端 JSON 反序列化还原物件 
 
相同的需求,以 ScriptManager PageMethods 改写的运作流程式如下


客户端物件 -> 1.呼叫伺服端的静态方法-> 修改对象属性 -> 2.接收伺服端回传的回呼函式
 
接下来我们就利用 ScriptManager PageMethods 来实作上述的范例,首先将 ScriptManager 控件的 EnablePageMethods 属性值设为 True。


<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="True" >
 
在页面上放置一个 HTMLButton,按钮 onclick 时执行 CallServer 函式来呼叫伺服端的静态方法。其中 CallServer 函式中会呼叫 GetUser 产生对象,ASP.NET 机制会自动将此对象利用 JSON 序列化,传给伺服端的 GetServerUser 静态方法。当伺服端执行结束,会以 CallServerResult 函式接回伺服端回传的结果并显示对象属性值。

 

 

<%@ Page Language="VB" AutoEventWireup="true" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    
<title>PageMethod</title>
    
<script type="text/jscript">
    
function GetUser(){
        
var oUser={
            ID : 
"007",
            Name : 
"jeff"
        };
        
return oUser;
    }
    
    
//执行伺服端函式
    function CallServer(){
        
var oUser = GetUser(); //准备传给伺服端的对象
        PageMethods.GetServerUser(oUser, CallServerResult);
    }
    
    
//回呼函式
    function CallServerResult(result){
        
//显示 CallBack 后的对象
        alert('Server:\n'+'ID:'+result.ID+'\nName:'+result.Name);        
    }
    
</script>
</head>
<body>
    
<form id="form1" runat="server">
        
<div>
            
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="True">
            
</asp:ScriptManager>
            
<input type="button" value="执行 PageMethod" onclick="CallServer()" /><br />
            
</div>
    
</form>
</body>
</html>

 

再来撰写伺服端的 GetServerUser 静态方法,并以 <System.Web.Services.WebMethod> 标记此方法。GetServerUser 方法的 Value 参数为 TUserData 型别,ASP.NET 机制会自动传客户端传入的字符串利用 JSON 反序列化为 TUserData 型别的对象,在此方法中修改对象的属性值,再回传给客户端。

 

    <System.Web.Services.WebMethod()> _
    
Public Shared Function GetServerUser(ByVal Value As TUserData) As TUserData
        
'修改客户端传入的对象,再传回客户端
        Value.ID = "012"
        Value.Name 
= "tony"
        
Return Value
    
End Function

<Serializable()> _
Public Class TUserData
    
Dim FID As String = String.Empty
    
Dim FName As String = String.Empty

    
Public Property ID() As String
        
Get
            
Return FID
        
End Get
        
Set(ByVal value As String)
            FID 
= value
        
End Set
    
End Property

    
Public Property Name() As String
        
Get
            
Return FName
        
End Get
        
Set(ByVal value As String)
            FName 
= value
        
End Set
    
End Property
End Class

 

执行结果如下

 

 

结论:「ScriptManager PageMethods」与「CallBack PageCommand」比较

 

依上述的示范,会不会发觉同样的需求使用「ScriptManager PageMethods」比「CallBack PageCommand」来处理显的更简单了,在「ScriptManager PageMethods」的运作流程中虽然使用了 JSON 序列化,可是在程序代码中完全不需自行处理 JSON 序列化/反序列化的动作。
理论上「ScriptManager PageMethods」应该可完全取代「CallBack PageCommand」,不过事实上并不尽然,正确的说是依使用时机而定。因为「ScriptManager PageMethods」是呼叫伺服端的静态方法,所以无法存取页面上的控件,而「CallBack PageCommand」则可以存取页面上的控件;在执行效能上「ScriptManager PageMethods」会优于「CallBack PageCommand」,因为它省略页面控件加载的动作。

posted @ 2008-08-26 21:29 jeff377 阅读(997) | 评论 (0)编辑

上一篇「CallBack PageCommand 与 JSON 初体验」中说明了在 CallBack 时,客户端可以接收伺服端传回的 JSON 字符串,在客户端 eval 取得 JSON 对象,使 JavaScript 可以直接操作伺服端传回的对象。其实在 ASP.NET AJAX 1.0 有提供相关类别来处理伺服端/客户端的 JSON 序列化/反列序化的需求。

伺服端处理 JSON 序列化的类别为
System.Web.Script.Serialization.JavaScriptSerializer

在伺服端处理序列化/反序列化的函式如下

    ''' <summary>
    
''' JSON 序列化。
    
''' </summary>
    
''' <param name="Value">物件。</param>
    Public Shared Function JsonSerialize(ByVal Value As ObjectAs String
        
Dim oSerializer As System.Web.Script.Serialization.JavaScriptSerializer

        oSerializer 
= New System.Web.Script.Serialization.JavaScriptSerializer()
        
Return oSerializer.Serialize(Value)
    
End Function

    
''' <summary>
    
''' JSON 反序列化。
    
''' </summary>
    
''' <param name="Text">JSON 字符串。</param>
    Public Shared Function JsonDeserialize(Of T)(ByVal Text As StringAs T
        
Dim oSerializer As System.Web.Script.Serialization.JavaScriptSerializer

        oSerializer 
= New System.Web.Script.Serialization.JavaScriptSerializer()
        
Return oSerializer.Deserialize(Of T)(Text)
    
End Function

 

客户端处理 JSON 序列化的类别为
Sys.Serialization.JavaScriptSerializer

 

JSON 序列化
var sJson= Sys.Serialization.JavaScriptSerializer.serialize(oObject)


JSON 反序列化
var oObject = Sys.Serialization.JavaScriptSerializer.deserialize(sJson)
 
我们来撰写一个范例测试客户端/伺服端 JSON 对象的传递,程序运作流程如下


客户端物件 -> 1.客户端 JSON 序列化 -> CallBack 呼叫伺服端 -> 2.伺服服端 JSON 反序列化还原对象 -> 修改对象属性
-> 3.伺服端 JSON 序列化 -> CallBack 回传客户端 -> 4.客户端 JSON 反序列化还原物件
 
首先修改 GetCallBackPageCommandEventReference 方法,原本 CommandArgument 是使用字符串常数,现修改为呼叫客户端 GetPageCommandParam 函式。

 

    ''' <summary>
    
''' 取得以 CallBack 方式引发 PageCommand 事件的客户端指令码。
    
''' </summary>
    
''' <param name="CommandName">命令名称。</param>
    
''' <param name="CommandArgument">命令自变量。</param>
    
''' <param name="ClientCallback">可接收成功的服务器端事件结果的客户端事件处理例程名称。</param>
    
''' <param name="Context">在启始回呼之前,于客户端上评估的客户端指令码。</param>
    Public Function GetCallBackPageCommandEventReference(ByVal CommandName As String, _
        
ByVal CommandArgument As String, _
        
ByVal ClientCallback As StringByVal Context As StringAs String
        
Dim sArgument As String

        
'sArgument = String.Format("'{0}${1}${2}'", PageEvent.PageCommand, CommandName, CommandArgument)

        
'PageCommand 事件会执行客户端 GetPageCommandParam 函式
        sArgument = String.Format("GetPageCommandParam('{0}',{1})", CommandName, CommandArgument)
        
Return Me.GetCallbackEventReference(FPage, sArgument, ClientCallback, Context)
    
End Function

 

客户端对应的 GetPageCommandParam 函式如下

 

    function GetPageCommandParam(commnadName,value){
        
var sArgument = Sys.Serialization.JavaScriptSerializer.serialize(value);
        
return "PageCommand$"+commnadName+'$'+sArgument;
    }

 

在页面上放置一个按钮,利用 GetCallBackPageCommandEventReference 来取得 CallBack PageCommand 的客户端指令码。其中 CommandArgument 自变量为 GetUser() ,此为执行 CallBack 时执行客户端的函式。ReceiveServerData 函式则是接收伺服端回传的结果。

 

        Button1.OnClientClick = Me.BeeScript.GetCallBackPageCommandEventReference( _
            
"User""GetUser()""ReceiveServerData"""& ";return false;"

 

伺服端的完整程序代码 (aspx.vb) 如下,在 PageCommand 事件中会接收客户端传入的 JSON 字符串将其转为对象,修改此对象属性值再回传给客户端。在伺服端会执行程序流程中的「2.伺服服端 JSON 反序列化还原对象」及「3.伺服端 JSON 序列化」二个步骤。

 

<Serializable()> _
Public Class TUserData
    
Dim FID As String = String.Empty
    
Dim FName As String = String.Empty

    
Public Property ID() As String
        
Get
            
Return FID
        
End Get
        
Set(ByVal value As String)
            FID 
= value
        
End Set
    
End Property

    
Public Property Name() As String
        
Get
            
Return FName
        
End Get
        
Set(ByVal value As String)
            FName 
= value
        
End Set
    
End Property
End Class

Partial Class _Default
    
Inherits Bee.Web.TBBasePage

    
Protected Sub Page_Load(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.Load
        Button1.OnClientClick 
= Me.BeeScript.GetCallBackPageCommandEventReference( _
            
"User""GetUser()""ReceiveServerData"""& ";return false;"
    
End Sub

    
Protected Sub _Default_PageCommand(ByVal sender As ObjectByVal e As Bee.Web.TBBasePage.PageCommandEventArgs) Handles Me.PageCommand
        
Dim oUser As TUserData
        
Dim sJson As String

        
'2.伺服服端 JSON 反序列化还原对象
        oUser = JsonDeserialize(Of TUserData)(e.CommandArgument)
        oUser.ID 
= "012"
        oUser.Name 
= "tony"

        
'3.伺服端 JSON 序列化
        sJson = Bee.Web.WebFunc.JsonSerialize(oUser)
        e.CallbackResult 
= sJson
    
End Sub
End Class

 

执行 CallBack 的按钮,输出的 HTML 码如下

 

<input type="submit" name="Button1" value="執行 PageCommand" onclick="WebForm_DoCallback('__Page',GetPageCommandParam('User',GetUser()),ReceiveServerData,&quot;&quot;,null,false);return false;" id="Button1" />

 

客户端的 JavaScrpt 程序代码如下所示,其中 GetUser 函式会取得 oUser 类别,包含 ID 及 Name 二个属性。执行按钮后会呼叫 GetPageCommandParam 函式,将 GetUser 取得对象执行步骤「1.客户端 JSON 序列化」,而伺服端回传给呼叫 ReceiveServerData 函式,执行步骤「4.客户端 JSON 反序列化还原对象」,并显示 CallBack 后的对象。

 

    <script type="text/jscript">
    
function ReceiveServerData(value){
        
//4.客户端 JSON 反序列化还原物件
        var oUser = Sys.Serialization.JavaScriptSerializer.deserialize(value)
        
//显示 CallBack 后的对象
        alert('Server:\n'+'ID:'+oUser.ID+'\nName:'+oUser.Name);
    }
    
    
function GetUser(){
        
var oUser={
            ID : 
"007",
            Name : 
"jeff"
        };
        
return oUser;
    }

    
function GetPageCommandParam(commnadName,value){
        
//1.客户端 JSON 序列化
        var sArgument = Sys.Serialization.JavaScriptSerializer.serialize(value);
        
return "PageCommand$"+commnadName+'$'+sArgument;
    }
    
</script>

 

执行结果如下

 

 

posted @ 2008-08-26 19:45 jeff377 阅读(951) | 评论 (1)编辑

JavaScript对象标记法,英文名称 JavaScript Object Notation(简称JSON),是一种文字格式标记法,相较于 XML 而言,JSON 明显更为简洁。而 JSON 这种精简的数据表示方式,非常适合用于 AJAX 的数据转输。
我们使用「BasePage 撰写 PageCommand 事件 (使用 CallBack)」一文中提及的 PageCommand 来执行 AJAX,并在 PageCommand 事件中回传 JSON 字符串,客户端以 JavaScript 取得回传的 JSON 对象。

在页面上放置一个 Button 来执行 CallBack PageCommand,Button.OnClientClick 使用 GetCallBackPageCommandEventReference 方法取得执行 PageCommand 事件的客户端指令码,客户端以 ReceiveServerData JavaScript 函式来接收伺服端的回传数据。当引发 PageCommand 时,透过 e.CallbackResult 属性来回传 JSON 字符串给客户端的 ReceiveServerData 函式。

 

aspx.vb 的程序代码如下

Partial Class Default
    
Inherits Bee.Web.TBBasePage

    
Protected Sub Page_Load(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.Load
        Button1.OnClientClick 
= Me.BeeScript.GetCallBackPageCommandEventReference("JSON""""ReceiveServerData"""& ";return false;"
    
End Sub

    
Protected Sub Page_PageCommand(ByVal sender As ObjectByVal e As TBBasePage.PageCommandEventArgs) Handles Me.PageCommand
        e.CallbackResult 
= "{'myCats': [ {'name': 'Hero', 'age': 5, 'color': 'silver' }, {'name': 'Euro', 'age': 2, 'color': ['brown', 'white', 'black']}]}"
    
End Sub
End Class

 

客户端负责接收 CallBack 伺服端回传数据的 ReceiveServerData 函式如下所示,会将传回的 JOSN 字符串使用 eval 函式来转换为 JSON 对象。

    <script type="text/jscript">
    
function ReceiveServerData(value){
        
var obj = eval ("(" + value + ")");
        alert(
'I have ' + obj.myCats.length + ' cats.');
        alert(obj.myCats[
0].name);
        alert(obj.myCats[
1].name);
    }
    
</script>

 

执行结果如下


 

 

 

参考数据:
http://www.json.org/
http://caterpillar.onlyfun.net/Gossip/AjaxGossip/JSON.html

posted @ 2008-08-21 06:24 jeff377 阅读(504) | 评论 (0)编辑

一般我们可以使用 FindControl 去找到子控件,但是若我们需要去找指定型别的父控件要如何寻找呢?例如去寻找指定 TextBox 控件所属的 UpdatePanel 父控件。针对上述的需求,以下将提供解决方式。
在 Control 有一个 Parent 属性,表示该控件的父控件,所以我们可以利用递归方式逐层往上判断 Parent 属性是否为指定型别,符合的话传回该父控件。以下的 FindParent 函式就是在寻找指定型别的父控件。
    ''' <summary>
    
''' 尋找指定型別的父控制項。
    
''' </summary>
    
''' <param name="Control">控制項。</param>
    
''' <param name="Type">欲尋找的型別。</param>
    Public Shared Function FindParent(ByVal Control As Control, ByVal Type As System.Type) As Control
        
If Control.Parent Is Nothing Then
            
Return Nothing
        
Else
            
If Type.IsInstanceOfType(Control.Parent) Then
                
Return Control.Parent
            
Else
                
Return FindParent(Control.Parent, Type)
            
End If
        
End If
    
End Function

 

如果要寻找 TextBox 所属的 UpdatePanel 则可以撰写如下程序代码即可。

 

        Dim oParent As Control
        oParent 
= FindParent(TextBox1, GetType(UpdatePanel))

posted @ 2008-08-20 22:12 jeff377 阅读(64) | 评论 (0)编辑

     摘要: 序列化是将对象状态转换为可保存或可传输格式的处理序。序列化的反面是还原序列化,它可以将数据流转换成对象。在 .NET 程序中常用的序列化方式如下表所示。 序列化类别 说明 .NET Framework 版本 XmlSerializer XML 序列化 2.0 SoapFormatter SOAP 序列化 2.0 BinaryFormatter 二进制序列化 2.0 DataContractSeri... 阅读全文

posted @ 2008-08-19 23:54 jeff377 阅读(144) | 评论 (0)编辑

前言
在「BasePage 撰写 PageCommand 事件」一文中说明如何在 PostBack 时引发 PageCommand 事件,本文将依此继续扩展,让 CallBack 也同样可以引发相同的 PageCommand 事件。
一般的 PostBack 会将整个页面的数据至伺服端,当伺服端处理完毕时,也是整个页面 Render 回传给客户端呈现;CallBack 是传开发人员定义的数据至伺服端,当伺服端处理完毕时,只传回字符串给自订的 JavaScript 函式处理。CallBack 比起 PostBack 相对轻量而有效率,二者可以视时机配合使用。例如页面数据数据储存时,整个页面的数据需要传至伺服端做储存动作,这时就适合使用 PostBack 处理;而当执行动作无须传回页面的所有数据时,例如在订单表身登打产品名称后,需要带回相对的产品编号、售价、单位...等相关资料,就非常适合使用 CallBack 来处理。
以「BasePage 撰写 PageCommand 事件」一文中的案例,当客户端响应讯问后传入伺服端时执行送审动作时,其实无须传回页面所有字段,只需传回客户端的响应值,所以这个案例其实比较适合使用 CallBack 来处理即可,整个程序执行流程如下。
按储存钮(客户端) -> PostBack -> 请假单储存(伺服端) -> 弹出询问讯息(客户端) -> CallBack -> 取得客户端响应决定是否送审(伺服端)
在本文将描述如何让 CallBack 也可以引发 PageCommand 事件,而以上述的相同案例,改用 CallBack 方式的 PageCommand 事件来处理。
 
程序实作
以「BasePage 撰写 PageCommand 事件」中的 TBBasePage 类别及 TBScriptManager 类别做扩展。首先 TBBasePage 类别需实作 CallBack 引发 PageCommand 事件,作法如下。
1.修改 PageCommand 事件自变量,加入 CallbackResult 属性,做为使用 CallBack 执行结果的回传字符串。
2.实作 ICallbackEventHandler 界面。
3.在 RaiseCallbackEvent 方法,判断 CallBack 的传入参数,决定是否引发 PageCommand 事件。

''' <summary>
''' 页面基础类别。
''' </summary>
Public Class TBBasePage
    
Inherits System.Web.UI.Page
    
Implements System.Web.UI.ICallbackEventHandler

    
Private FCallbackResult As String = String.Empty

#Region " PageCommand 事件 "

    
''' <summary>
    
''' DayCommand 事件自变量。
    
''' </summary>
    Public Class PageCommandEventArgs
        
Inherits System.EventArgs
        
Private FCommandName As String = String.Empty
        
Private FCommandArgument As String = String.Empty
        
Private FCallbackResult As String = String.Empty

        
''' <summary>
        
''' 命令名称。
        
''' </summary>
        Public Property CommandName() As String
            
Get
                
Return FCommandName
            
End Get
            
Set(ByVal value As String)
                FCommandName 
= value
            
End Set
        
End Property

        
''' <summary>
        
''' 命令自变量。
        
''' </summary>
        Public Property CommandArgument() As String
            
Get
                
Return FCommandArgument
            
End Get
            
Set(ByVal value As String)
                FCommandArgument 
= value
            
End Set
        
End Property

        
''' <summary>
        
''' CallBack 执行结果的回传字符串。
        
''' </summary>
        Public Property CallbackResult() As String
            
Get
                
Return FCallbackResult
            
End Get
            
Set(ByVal value As String)
                FCallbackResult 
= value
            
End Set
        
End Property
    
End Class

    
''' <summary>
    
''' 页面命令事件。
    
''' </summary>
    < _
    System.ComponentModel.Description(
"页面命令事件。") _
    
> _
    
Public Event PageCommand(ByVal sender As ObjectByVal e As PageCommandEventArgs)

    
''' <summary>
    
''' 引发 PageCommand 事件。
    
''' </summary>
    Protected Overridable Sub OnPageCommand(ByVal e As PageCommandEventArgs)
        
RaiseEvent PageCommand(Me, e)
    
End Sub

#End Region

#Region " ICallbackEventHandler 界面 "

    
Public Sub RaiseCallbackEvent(ByVal eventArgument As StringImplements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent
        
Dim oArgument() As String
        
Dim oEventArgs As PageCommandEventArgs

        oArgument 
= Split(eventArgument, "$")
        
If oArgument.Length = 3 Then
            
If SameText(oArgument(0), "PageCommand"Then
                
'引发 PageCommand 事件
                oEventArgs = New PageCommandEventArgs()
                oEventArgs.CommandName 
= oArgument(1)
                oEventArgs.CommandArgument 
= oArgument(2)
                
Me.OnPageCommand(oEventArgs)
                FCallbackResult 
= oEventArgs.CallbackResult
            
End If
        
End If
    
End Sub

    
Public Function GetCallbackResult() As String Implements System.Web.UI.ICallbackEventHandler.GetCallbackResult
        
Return FCallbackResult
    
End Function

#End Region

    
''' <summary>
    
''' 判断二字符串是否相同(不区分大小写)。
    
''' </summary>
    
''' <param name="S1">第一个字符串。</param>
    
''' <param name="S2">第二个字符串。</param>
    Public Shared Function SameText(ByVal S1 As StringByVal S2 As StringAs Boolean
        
If S1 Is Nothing Then
            
Return S2 Is Nothing
        
End If
        
Return S1.Equals(S2, StringComparison.CurrentCultureIgnoreCase)
    
End Function

End Class

 

然后在 TBScriptManager 类别新增一个 GetCallBackPageCommandEventReference方法,取得使用 CallBack 方式引发 PageCommand 事件的客户端指令码。

''' <summary>
''' 客户端指令码管理。
''' </summary>
Public Class TBScriptManager

    
''' <summary>
    
''' 取得以 CallBack 方式引发 PageCommand 事件的客户端指令码。
    
''' </summary>
    
''' <param name="CommandName">命令名称。</param>
    
''' <param name="CommandArgument">命令自变量。</param>
    
''' <param name="ClientCallback">可接收成功的服务器端事件结果的客户端事件处理例程名称。</param>
    
''' <param name="Context">叫用客户端回呼之客户端函式的名称。 </param>
    Public Function