在MSDN上看到的文章,原文名稱爲Who Is Looking: Building a Custom ASP.NET Control that uses Javascript, Cascading Style Sheets, and Ajax,下載以後經過測試,感覺確實不錯,下面根據我的理解整理了一下其實現的思路,推薦給大家。
命如其名,這個控件的功能就是在某個客戶瀏覽網頁的時候,這個客戶的消息就會出現在瀏覽這個網頁的所有客戶端上。當某個客戶端離開這個網頁的時候,這個客戶的消息就會從所有別的客戶端消失。
程序運行效果:
創建ASP.NET自定義控件
在Visual Studio中,所有的ASP.NET 2.0控件都是自定義控件,創建自己的自定義控件一般需要完成以下三步。
(1)在站點APP_Code下創建一個新類;
(2)修改這個類,讓它成爲WebControl類(包含在System.Web.UI.WebControls命名空間)的派生類;
(3)重寫基類(即WebControl類)的RenderContents()方法。
下面是一個最簡單的ASP.NET控件,它的功能只有一個,顯示"Hellow World"。
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace myControls
{
public class HelloWorld : WebControl
{
protected override void RenderContents(HtmlTextWriter writer)
{
writer.Write("Hello World");
}
}
}
using System.Web.UI;
using System.Web.UI.WebControls;
namespace myControls
{
public class HelloWorld : WebControl
{
protected override void RenderContents(HtmlTextWriter writer)
{
writer.Write("Hello World");
}
}
}
自定義控件創建好之後,有三種方法將其添加到網頁中。
第一種選擇是首先在aspx文件添加註冊控件的代碼:
<%@ Register TagPrefix="custom" Namespace="myControls" %>
其中TagPrefix屬性的值可隨意選取,Namespace屬性的值必須與你創建的自定義控件一致,然後在該頁的任意位置均可引用此控件 。
<custom:HelloWorld ID="HelloWorld1" runat="server" />
第二種選擇是在Web.Config文件中註冊此控件,這樣你就可以在所有的aspx頁面中引用此控件。相關配置如下:
<pages>
<controls>
<add tagPrefix="custom" namespace="myControls"/>
</controls>
</pages>
<controls>
<add tagPrefix="custom" namespace="myControls"/>
</controls>
</pages>
最後一種方式是將控件添加到Visual Studio工具箱中,使用時直接拖拉到網頁中。但這個時候你不能在APP_Code文件夾下創建這個控件,而必須將其創建爲獨立的程序集,具體方法本文後面將會提到。創建好獨立的自定義控件後,右鍵單擊Visual Studio工具箱,選擇“選擇項”,之後會彈出一個對話框,從中選擇你自己的程序集,自定義控件將自動出現在工具箱上。
嵌入Javascript
爲了獲得更好的客戶端效果,我們需要引入Javascript和CSS樣式表。在ASP.NET中,有一個類叫作ClientScriptManager,可以很方便的對Javascript進行操作,其中比較重要的方法有:- RegisterClientScriptBlock()
- RegisterStartupScript()
- RegisterClientScriptInclude()
- GetWebResourceUrl()
<script type="text/Javascript" src="SomeScript.js"></script>
這種方式的缺點在於發佈程序的時候需要將獨立的js文件一起發佈,解決這個問題的辦法就是使用GetWebResourceUrl()方法,通過這個方法可以把js文件直接嵌入到控件當中,換句話說就是你發佈的程序集將同時包含自定義控件和獨立的js文件。與前面註冊控件一樣,在APP_Code裏創建的自定義控件是不能同時包含js文件的,需要將其發佈爲獨立的程序集。
首先我們在Visual Studio裏創建一個新的項目,類型選擇類庫。爲了在類庫工程裏創建自定義控件,首先需要添加對System.Web.Dll的引用,然後選擇工程裏的js文件,將其生成事件屬性修改爲嵌入資源。接下來需要在AssemblyInfo中對每一個嵌入的資源添加WebResource屬性,只需打開Properties裏的AssemblyInfo.cs文件,添加以下代碼:
[assembly: WebResource("WhoIsLooking.WhoIsLooking.js", "text/javascript")]
// Add Javascript include
string scriptUrl = Page.ClientScript.GetWebResourceUrl( this.GetType(),
"WhoIsLooking.WhoIsLooking.js");
Page.ClientScript.RegisterClientScriptInclude("WhoIsLooking", scriptUrl);
string scriptUrl = Page.ClientScript.GetWebResourceUrl( this.GetType(),
"WhoIsLooking.WhoIsLooking.js");
Page.ClientScript.RegisterClientScriptInclude("WhoIsLooking", scriptUrl);
嵌入CSS樣式表
方法與嵌入Javascript類似,在AssemblyInfo.cs中添加:[Assembly: WebResource("WhoIsLooking.WhoIsLooking.css", "text/css")]
在OnPreRender方法中添加:
// Add style sheet to parent page
string cssUrl = Page.ClientScript.GetWebResourceUrl(this.GetType(),
"WhoIsLooking.WhoIsLooking.css");
HtmlLink cssLink = new HtmlLink();
cssLink.Href = cssUrl;
cssLink.Attributes.Add("rel", "stylesheet");
cssLink.Attributes.Add("type", "text/css");
this.Page.Header.Controls.Add(cssLink);
// Add class name
this.CssClass = "WhoIsLooking";
string cssUrl = Page.ClientScript.GetWebResourceUrl(this.GetType(),
"WhoIsLooking.WhoIsLooking.css");
HtmlLink cssLink = new HtmlLink();
cssLink.Href = cssUrl;
cssLink.Attributes.Add("rel", "stylesheet");
cssLink.Attributes.Add("type", "text/css");
this.Page.Header.Controls.Add(cssLink);
// Add class name
this.CssClass = "WhoIsLooking";
使用Ajax
WhoIsLooking控件採用Ajax技術實時顯示訪客信息,Ajax是Asynchronous Javascript和 XML的縮寫,利用這個技術可以在不刷新整個頁面的情況下實現客戶端與服務器端之間的數據傳送。爲了在ASP.NET自定義控件中實現Ajax需要完成以下三個步驟:1 使用 GetCallbackEventReference()發起客戶端請求;
2 實現ICallBackEventHandler 接口響應客戶端的請求,這個接口有兩個方法需要實現:RaiseCallbackEvent()方法以及GetCallbackResult()方法。
3 創建Javascript客戶端函數獲取返回的數據並進行相應的操作。
WhoIsLooking每5秒鐘發起一次請求,需在OnPreRender()方法中添加以下代碼:
string callback = Page.ClientScript.GetCallbackEventReference
(
this,
null,
"WhoIsLooking.UpdateDisplay",
String.Format("'{0}'", this.ClientID),
"WhoIsLooking.CallbackError",
true);
string startupScript = String.Format("setInterval( \"{0}\", {1} );", callback, _PollingInterval * 1000);
Page.ClientScript.RegisterStartupScript(this.GetType(), "WhoIsLooking", startupScript, true);
(
this,
null,
"WhoIsLooking.UpdateDisplay",
String.Format("'{0}'", this.ClientID),
"WhoIsLooking.CallbackError",
true);
string startupScript = String.Format("setInterval( \"{0}\", {1} );", callback, _PollingInterval * 1000);
Page.ClientScript.RegisterStartupScript(this.GetType(), "WhoIsLooking", startupScript, true);
接下來需要重寫RaiseCallbackEvent() 及GetCallbackResult()方法,RaiseCallbackEvent()方法將當前用戶加入訪客列表,同時也將離開的用戶從列表中刪除。GetCallbackResult()返回訪客的信息,包括用戶帳號,姓名,停留時間,瀏覽器信息,主機名,操作系統信息等。該方法的返回值爲一個JSON數組,JSON是Ajax請求中表示信息的標準格式(關於JSON的更多介紹,請訪問json.net)。例如,如果同時有兩個用戶正在瀏覽當前網頁,JSON的值將會是這樣:
[{userId:"fooglm45cjcycw55qi4yluvk",userName:"SUPEREXPERT\\Steve", duration:"0 minute(s)", browser: "IE 7.0", remoteHost: "superexpert.com", platform: "WinXP"},{userId:"1kqatn55sxc4vi55ummxghil",userName:"SUPEREXPERT\\Bill", duration:"0 minute(s)", browser: "Firefox 1.5.0.11", remoteHost: "superexpert.com", platform: "WinXP"}]
最後,WhoIsLooking控件通過UpdateDisplay()方法在客戶端顯示用戶信息,該方法爲每一個用戶創建一個<div>層存放用戶信息。
譯者注:在原文中,WhoIsLooking的實現同時提供了C#和VB的代碼,我這裏只貼出了C#的代碼,使用VB的朋友可到原文中查看,或直接到下載好的源文件中查看。
完整源代碼下載(包括C#和VB)