|
constructor TWebPageInfo.Create(AAccess: TWebPageAccess; const APageFile, APageName: string;
const ACaption, ADescription, AViewAccess: string);
在 TWebUserList 中 有 一 個 處 理 AccessRight 的 事 件 , 與 上 面 的 程 式 搭 配 後 , 你 就 可 以 建 構 出 完 整 的 使 用 者 控 管 功 能 了 ! 除 了 Adapter 、 WebPageInfo 、 AdapterAction 之 外 , 我 們 也 可 以 設 定 某 個 Adapter Control Items 針 對 權 限 的 不 同 做 出 正 確 的 反 應 。 例 如 你 可 以 設 定 TAdapterDisplayField 的 ViewMode 為 vmToggleOnAccess , 這 樣 這 個 Control 就 會 在 使 用 者 沒 有 Modify 權 限 時 轉 變 為 純 顯 示 , 在 使 用 者 擁 有 Modify 權 限 時 轉 變 為 Edit 。 看 起 來 好 像 很 不 錯 , 事 實 上 她 有 一 個 問 題 , 就 像 是 我 們 的 MasterDetailEdit 網 頁 是 在 使 用 者 一 進 入 網 頁 後 就 是 編 修 模 式 , 一 開 始 沒 啥 錯 誤 , 所 有 的 Control 因 為 使 用 者 沒 有 編 修 的 權 限 全 都 進 入 了 純 文 字 的 顯 示 , 但 你 別 忘 了 , 我 們 將 AdapterMode 設 成 Edit 了 , 這 也 代 表 著 我 們 移 動 記 錄 會 觸 發 Update 的 動 作 。 在 這 個 Update 函 式 的 第 一 行 就 呼 叫 了 CheckModifyAccess , 因 為 使 用 者 沒 有 編 修 的 權 限 , 當 然 例 外 就 跳 出 來 了 , 那 我 們 就 不 能 使 用 這 個 功 能 了 嗎 ? 呵 ! 山 不 轉 路 轉 , 我 們 可 以 在 MasterDetailEdit.OnBeforeDispatchPage 事 件 中 加 上 處 理 權 限 的 程 式 碼 :
procedure TMasterDetailEdit.WebPageModuleBeforeDispatchPage(
Sender: TObject; const PageName: String; var Handled: Boolean);
var
UserItem:TWebUserItem;
EditMode:string;
begin
UserItem:=Home.WebUserList1.UserItems.FindUserName(Home.EndUserSessionAdapter1.UserID);
EditMode:='''''''';
if Assigned(UserItem) then
begin
if UserItem.AccessRights = wdmData.dsAdaptOrder.ModifyAccess then
EditMode:=''''Edit'''';
end;
AdapterFieldGroup1.AdapterMode:=EditMode;
AdapterGrid1.AdapterMode:=EditMode;
end;
然 後 將 所 有 的 AdapterEditColumn 以 及 AdapterDisplayField 的 ViewMode 都 改 成 vmToggleOnAccess 就 可 以 正 確 的 執 行 了 。 其 實 這 並 不 算 是 Bug , 只 是 使 用 的 方 式 不 同 罷 了 , 但 這 樣 還 是 不 足 以 完 成 整 個 MasterDetailEdit 的 權 限 控 制 , 使 用 者 還 是 可 以 使 用 那 些 按 紐 。 雖 然 會 產 生 例 外 , 也 不 會 更 動 到 資 料 , 但 感 覺 上 總 是 不 太 對 , 其 實 我 們 可 以 藉 由 設 定 DataSetAdapter.Actions 中 的 AdapterAction.ExecuteAccess 特 性 值 及 ActionButton.HiddenOptions 特 性 值 為 [bhoHiddOnNoExecuteAccess] , 這 樣 就 可 以 視 權 限 來 決 定 隱 藏 或 顯 示 按 紐 , 範 例 中 的 MasterEditDetail 網 頁 已 經 有 完 整 的 權 限 控 制 了 , 你 可 以 用 code6421 密 碼 是 1234 登 入 後 就 可 以 修 改 了 , 如 果 沒 有 登 入 的 話 , 你 就 只 能 夠 看 到 純 文 字 的 顯 示 。
5-4 將 Session 存 放 於 檔 案 中
控 制 Cookie 的 保 存 期 限 是 一 種 較 簡 單 的 方 法 , 但 是 這 種 方 式 有 個 致 命 的 缺 點 。 當 我 們 的 Web 程 式 被 關 閉 後 ( 指 整 個 程 式 被 從 記 憶 體 中 移 除 , 例 如 你 將 Web Server 或 電 腦 重 新 啟 動 ) , 因 為 Session 是 存 放 於 記 憶 體 之 中 , 所 以 也 跟 著 程 式 的 停 止 而 消 失 了 。 這 時 使 用 者 所 保 留 的 Cookie 也 就 沒 有 作 用 了 , 要 解 決 這 個 問 題 , 我 們 有 兩 種 選 擇 , 較 簡 單 的 方 法 是 在 程 式 停 止 之 前 , 將 整 個 Sessions 全 數 存 入 資 料 庫 中 , 下 次 啟 動 時 再 由 資 料 庫 讀 取 後 , 回 存 至 Sessions 物 件 。 這 種 方 法 有 個 缺 點 , 因 為 我 們 是 存 放 整 個 Sessions , 因 此 可 能 會 存 入 一 些 多 餘 的 資 料 , 例 如 暫 時 性 的 變 數 、 或 是 一 些 根 本 就 不 值 得 保 存 的 資 料 , 這 很 浪 費 記 憶 體 與 空 間 。 第 二 種 方 式 是 只 存 放 目 前 所 使 用 的 Session , 這 個 方 式 較 前 者 好 , 但 還 是 有 一 樣 的 問 題 , 只 是 問 題 的 情 況 較 簡 單 , 因 為 我 們 只 存 放 一 個 Session , 因 此 浪 費 的 部 份 也 只 限 於 這 個 Session 物 件 中 , 比 起 第 一 種 方 法 來 的 好 多 了 。 這 一 節 所 使 用 的 範 例 程 式 是 Demo2 , 請 你 開 啟 範 例 程 式 對 照 著 看 。
整 個 程 式 的 概 念 是 來 自 於 Nick Hodges , 我 取 用 了 部 份 的 程 式 碼 , 將 她 整 合 至 我 的 範 例 程 式 中 。 首 先 我 先 介 紹 在 Home Page Module 中 的 兩 個 工 具 函 式 :
// Write a session to a stream
procedure THome.SaveSession(AID: TSessionID; aStream: TStream);
var
TempSessions: TSessions;
TempItem: TSessionItem;
begin
TempSessions := TSessions.Create;
try
TempItem := TSessionItem.Create(TempSessions);
if Sessions.GetSession(AID, TempItem) then
TempSessions.SaveToStream(aStream)
else
Assert(False, ''''Session not found'''');
finally
TempSessions.Free;
end;
end;
// Update or Add all name/value pairs from the saved session to a new or existing session
procedure THome.RestoreSession(AID: TSessionID; aStream: TStream);
var
TempSessions: TSessions;
Item: TSessionItem;
I: Integer;
begin
if aStream.Size <> 0 then // if there is no data there, don''''t do anything
begin
TempSessions := TSessions.Create;
try
TempSessions.LoadFromStream(aStream);
if AID = '''''''' then
// Create a new session
AID := SessColn.Sessions.StartSession
else
Assert(Sessions.SessionExists(AID), ''''Could not find session '''' + AID);
Item := TempSessions.Items[0] as TSessionItem;
for I := 0 to Item.Items.Count - 1 do
Sessions.SetItemValue(AID, Item.Items.Names[I], Item.Items.Variants[I]);
finally
TempSessions.Free;
end;
end;
end;
SaveSession 函 式 的 功 用 是 取 出 Sessions 中 符 合 傳 入 的 SessionID 的 Session 取 出 , 由 於 Session 物 件 本 身 並 未 提 供 SaveToStream 的 功 能 , 這 個 功 能 位 於 Sessions 物 件 之 中 , 因 此 Nick 建 立 了 一 個 暫 時 性 的 Sessions 物 件 , 並 將 取 得 的 Session 複 製 到 暫 存 的 Session 物 件 之 中 , 最 後 再 呼 叫 SaveToStream 來 存 入 Session 物 件 至 Stream 中 。
RestoreSession 則 與 SaveSession 完 全 相 反 , 她 的 功 用 是 由 Stream 中 取 出 Session 物 件 , 接 著 將 她 回 存 到 現 行 的 Session 中 。 有 了 這 兩 個 工 具 函 式 後 , 我 們 撰 寫 程 式 就 方 便 多 了 。 接 下 來 我 們 先 規 劃 一 下 要 如 何 運 用 這 兩 個 函 式 建 立 可 將 Session 保 存 至 資 料 庫 的 程 式 。 下 面 是 我 們 程 式 的 流 程 圖 :

當 使 用 者 第 一 次 登 入 時 , 她 必 須 要 到 填 寫 個 人 資 料 的 網 頁 中 填 寫 資 料 , 在 這 個 網 頁 中 我 們 製 作 了 一 個 確 定 的 按 紐 , 執 行 後 我 們 就 利 用 資 料 庫 以 及 SaveSession 函 式 來 將 Session 存 入 資 料 庫 。 這 樣 使 用 者 第 二 次 登 入 時 , 系 統 就 可 以 由 資 料 庫 中 取 得 上 次 的 Session 資 料 , 接 著 使 用 RestoreSession 函 式 將 她 還 原 回 Session 物 件 。 我 們 建 構 一 個 新 的 Table , 在 其 中 建 立 三 個 欄 位 , USER_ID 、 SESSION_ID 、 SESSION_INFO , USER_ID 用 來 儲 存 使 用 者 登 入 的 ID , SESSION_ID 則 是 儲 存 使 用 者 登 入 後 系 統 所 產 生 的 SessionID , SESSION_INFO 是 用 在 儲 存 Session 物 件 上 。

接 著 我 們 要 撰 寫 儲 存 Session 至 資 料 庫 的 程 式 碼 , 我 們 選 擇 寫 在 使 用 者 填 入 個 人 資 料 並 按 下 確 定 按 紐 的 OnExecute 事 件 中 :
procedure TProfile.AdaptSaveProfileExecute(Sender: TObject;
Params: TStrings);
procedure SaveSession;
var
S:TStream;
begin
if not dmData.tbSessionFile.Active then
dmData.tbSessionFile.Open;
if dmData.tbSessionFile.Locate(''''USER_ID'''',WebContext.EndUser.DisplayName,[]) then
dmData.tbSessionFile.Edit
else
dmData.tbSessionFile.Append;
dmData.tbSessionFile.FieldByName(''''USER_ID'''').Value:=WebContext.EndUser.DisplayName;
dmData.tbSessionFile.FieldByName(''''SESSION_ID'''').Value:=Session.SessionID;
S:=dmData.tbSessionFile.CreateBlobStream(dmData.tbSessionFile.FieldByName(''''SESSION_INFO''''),bmWrite);
try
Home.SaveSession(Session.SessionID,S);
dmData.tbSessionFile.Post;
finally
S.Free;
end;
end;
begin
上一页 [1] [2] [3] 下一页 [聊天工具]Gmail推出新功能:Web Clip__天极Yesky [聊天工具]Web MSN你玩了吗__天极Yesky [系统软件]Web Browser Express 概述 [系统软件]对Internet Explorer Web 控件做一点修改 [常用软件]小技巧:三步实现Web迅雷录制PPLive节目 [常用软件]天网防火墙:打开WEB和FTP服务 [VB.NET程序]使用VB.Net做一个配置web.config功能的WinForm(原… [VB.NET程序]vb.net控件、web service简述 [VB.NET程序]使用vbscript脚本调用web服务 [VB.NET程序]*** Web 存储系统窗体:窗体注册表 (new)***
|