從 SF.NET 下載 NBear 最新版組件、原始碼與教程。
本文僅涉及 NBear.Web 組件。若要在專案中使用本文功能,只需加入 NBear.Web.dll 參考。NBear 基於 .NET Framework 2.0 / C# 2.0 / ASP.NET 2.0,故功能僅適用於 ASP.NET 2.0 開發。
本文討論的功能定義於 NBear.Web.UI 命名空間下的 Page、MasterPage、UserControl 擴展基類中。欲使用這些功能,必須將這些類設為 WebForm、MasterPage 或 User Control 的基類。三個基類的擴展功能基本等價,下文以 Page 為主演示,其他類似。
範例頁面 HelperMethodsDemo.aspx 演示了一組 NBear.Web.UI.Page 基類的擴展輔助方法。
用於便利獲取 QueryString 與 Form 傳遞的參數。若同鍵值同時存在於 Form 與 QueryString,優先返回 Form 參數。
Response.Write(string.Format("intParam = {0}<br />", GetIntParam("intParam", 0)));
Response.Write(string.Format("strParam = {0}<br />", GetStringParam("strParam", string.Empty)));
Response.Write(string.Format("dtParam = {0}<br />", GetDateTimeParam("dtParam", DateTime.MinValue)));
此組函式包含兩個參數,第二個參數指定預設錯誤返回值;若鍵值不存在或型別轉換失敗,返回該預設值。
將任意型別物件轉換為指定強型別物件,簡化 (ReturnType)obj 語法。特別適合用於頁面資料繫結運算式中,取代基於反射的 eval 語法。
Session["hello time"] = DateTime.Now;
Response.Write(string.Format("Test StrongTyped<T>(), current time ticks = {0}<br />", StrongTyped<DateTime>(Session["hello time"]).Ticks));
常見字串轉換輔助方法,範例頁面演示兩個方法,此處不贅述。
透過 Page.ClientScriptFactory 存取一組生成客戶端 JS 腳本的伺服端方法,封裝常見 JS 代碼構造。優點:構建客戶端腳本過程獲得編譯期錯誤檢測,避免手寫 JS 產生難以除錯的錯誤。
範例頁面 ClientScriptFactoryDemo.aspx 演示兩種典型場景:
<%= ClientScriptFactory.WrapScriptTag(ClientScriptFactory.PopAlert("Page Loaded")) %>
直接向頁面輸出一個 <script> 區塊,包含 alert 效果。若不使用 WrapScriptTag,生成腳本不會包裹在 script 標籤中;在既有 script 區塊中插入片段時無需包裹。
Response.Write(ClientScriptFactory.WrapScriptTag(string.Format("var result = {0}; if (result) {1} else {2}",
ClientScriptFactory.PopConfirm("Are you sure?"),
ClientScriptFactory.PopAlert("Yes"),
ClientScriptFactory.PopAlert("No")),
ClientScriptFactory.PopAlert("Done")));
在事件處理函數中輸出較複雜的客戶端 JS 腳本。
基於 .resx 與 .resources 資源檔,支援多語言網站架構。Global.asax 與 GlobalizationDemo.aspx 演示用法。
註:ASP.NET 2.0 本身提供優秀的多語言方案,本組件作為另一選擇,一般仍建議使用內建方案。
void Application_Start(object sender, EventArgs e)
{
if (NBear.Web.UI.WebHelper.DefaultCulture.ToString().ToLower() != "en-us")
{
NBear.Web.UI.WebHelper.DefaultCulture = new System.Globalization.CultureInfo("zh-CN");
}
NBear.Web.UI.WebHelper.LoadResources("Strings");
}
public partial class GlobalizationDemo : NBear.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
for (int i = 0; i < DropDownList1.Items.Count; i++)
{
ListItem item = DropDownList1.Items[i];
if (item.Value.ToLower() == NBear.Web.UI.WebHelper.DefaultCulture.ToString().ToLower())
{
DropDownList1.SelectedIndex = i;
}
}
}
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
NBear.Web.UI.WebHelper.DefaultCulture = new CultureInfo(DropDownList1.SelectedValue);
NBear.Web.UI.WebHelper.LoadResources("Strings");
}
}
ASP.NET 2.0 下資源檔通常置於 App_GlobalResources 特殊目錄。範例中定義了 Strings.en-US.resx 與 Strings.zh-CN.resx,各包含一個 Hello 鍵值。
目錄中另含 ResGen.cmd 批次檔,用於將 resx 編譯為 bin 目錄下的 .resources 檔,框架才能存取。內容如下:
@echo off
"C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\resgen.exe" Strings.en-US.resx ..\bin\Strings.en-US.resources
"C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\resgen.exe" Strings.zh-CN.resx ..\bin\Strings.zh-CN.resources
修改或新增資源項目時,只需修改 resx 並重新點擊 ResGen.cmd 編譯,無需重新編譯整個網站程式。
AjaxHelper 源自 Teddy 早期同名 Ajax 框架,原基於 prototype 封裝,實現基於 UserControl 的各種 Ajax 效果。ASP.NET 2.0 發布後,已整合至 NBear 擴展頁面基類,並改用內建 Callback 機制取代 prototype 依賴,使用更簡單優雅。
範例頁面 AjaxDemo.aspx 與 AjaxDemo2.aspx 演示整合到 Page 基類的 Ajax 功能。
目前支援兩種使用模式:
執行 Ajax 效果後,若點擊瀏覽器重新整理或按 F5,頁面狀態回復到初始載入狀態。
AjaxDemo.aspx 演示此模式。使用 AjaxHelper 的頁面必須覆寫 EnableAjaxCallback 屬性並返回 true,否則不會生成 Ajax 回調支援腳本。
public partial class AjaxDemo : NBear.Web.UI.Page
{
protected override bool EnableAjaxCallback
{
get { return true; }
}
}
AjaxDemo.aspx 頁面內容:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="AjaxDemo.aspx.cs" Inherits="AjaxDemo" %>
<html xmlns="https://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script language="javascript" type="text/javascript">
function customFunc(data) { alert(data); }
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<input type="button" value="Test Callback" onclick="<%= Ajax.Callback("AjaxTemplates/Simple", null, "customFunc") %>" />
<input type="button" value="Test Update" onclick="<%= Ajax.Update("AjaxTemplates/DataBinding", "outputElementId", "num=5", "customFunc") %>" />
<br /><br />
<div id="outputElementId"></div>
</div>
</form>
</body>
</html>
方法說明:
Ajax.Callback(ajaxTemplate, parms, onComplete):執行指定 ajaxTemplate 回調,parms 傳遞類 QueryString 參數,onComplete 為處理回調返回內容的客戶端函數名。Ajax.Update(ajaxTemplate, outputElementId, parms, onComplete):多一個 outputElementId 參數,指定含 innerHTML 的標籤 ID(如 div、span),回調成功內容自動替換至該標籤 innerHTML。onComplete 可傳 null。兩個按鈕分別調用 Simple 與 DataBinding 兩個 AjaxTemplate(特殊 UserControl,置於 AjaxTemplates 目錄)。所有作為 AjaxTemplate 的 UserControl 必須繼承 NBear.Web.UI.AjaxTemplate。若需在 code behind 處理內容(如資料繫結),不可在 Page_Load 中處理,必須覆寫 OnAjaxTemplatePreRender() 方法。Page_Load 代碼永不執行。
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Simple.ascx.cs" Inherits="AjaxTemplates_Simple" %>
Hello Simple!
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="DataBinding.ascx.cs" Inherits="AjaxTemplates_DataBinding" %>
<asp:GridView ID="GridView1" runat="server"></asp:GridView>
public partial class AjaxTemplates_DataBinding : NBear.Web.UI.AjaxTemplate
{
private SampleEntity[] objs = null;
private void LoadSampleEntities(int num)
{
objs = new SampleEntity[num];
for (int i = 0; i < num; i++)
{
objs[i] = EntityFactory<SampleEntity>.CreateObject();
objs[i].ID = i + 1;
objs[i].Name = Guid.NewGuid().ToString();
}
}
public override void OnAjaxTemplatePreRender(System.Collections.Generic.Dictionary<string, string> callbackParams)
{
LoadSampleEntities(int.Parse(callbackParams["num"]));
GridView1.DataSource = objs;
GridView1.DataBind();
}
}
注意:重載 OnAjaxTemplatePreRender 執行繫結,並從 callbackParams 取得頁面傳遞的 num 參數。
相對模式一,採用模式二時,瀏覽器重新整理可記憶並自動重新執行上一次模式二的 Ajax 回調。
AjaxDemo2.aspx 演示此模式,與 AjaxDemo.aspx 僅 aspx 檔不同:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="AjaxDemo2.aspx.cs" Inherits="AjaxDemo2" %>
<html xmlns="https://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Untitled Page</title>
<script language="javascript" type="text/javascript">
function customFunc(data) { alert(data); }
</script>
</head>
<body onload="<%= Ajax.OnPageLoad() %>">
<form id="form1" runat="server">
<div>
<input type="button" value="Test Callback" onclick="<%= Ajax.Callback2("AjaxTemplates/Simple", null, "customFunc") %>" />
<input type="button" value="Test Update" onclick="<%= Ajax.Update2("AjaxTemplates/DataBinding", "outputElementId", "num=5", "customFunc") %>" />
<br /><br />
<div id="outputElementId"></div>
</div>
</form>
</body>
</html>
兩點差異:
<body onload="<%= Ajax.OnPageLoad() %>">:頁面載入後自動重新執行上一次模式二的 Ajax 回調。Ajax.Callback2 與 Ajax.Update2 取代模式一的方法,參數列表與含義完全相同。執行 AjaxDemo2.aspx 點擊按鈕後,網址列會附加 #... 代碼,包含上一次 Ajax 回調所有參數。Ajax.OnPageLoad() 依此重新執行。
模式一與二可在同頁混合使用,但只有最後一次 Ajax.Callback2 或 Ajax.Update2 的回調會在重新整理時自動重複執行。
本文結束