ASP.NET AJAX示例:文檔鎖定程序
ASP.NET AJAX示例:文檔鎖定程序
此示例屬于簡單的文檔管理系統。如任何正式的文檔管理系統一樣,我們必須提供并發管理。即,我們需要一種方法來處理兩個用戶嘗試編輯同一個文檔的問題。我們將通過創建某種類型的鎖定機制,來使正在編輯的文檔不能再由另一個用戶編輯,從而達到上述目的。我們將利用 AJAX 讓用戶有更愉快的鎖定機制體驗。首先,我們將創建用戶嘗試編輯但無法編輯(因為其他用戶正在編輯該文檔)的文檔隊列,當這些文檔可用時自動通知用戶。其次,我們將確保當用戶關閉其瀏覽器或導航到其他位置時,解除對文檔的鎖定。后一個功能幫助確保文檔不會永遠處于鎖定狀態。為此,在本指南中,我們將跳過與 AJAX 實現不相關的功能;但是,可下載項目包含所有功能。
首先,當用戶嘗試編輯文檔時,我們會嘗試對其建立排它鎖,如果失敗,我們會將此文檔添加到用戶的隊列然后使其返回到主頁。對此處的 AJAX 沒有什么特別之處,但是我們將查看一下代碼,以便給出示例必要的上下文。在用于編輯的 Page 的 OnLoad 事件中,添加以下代碼。
- //C#:ASP.NET AJAX示例
- if (!Page.IsPostBack)
- {
- //應驗證用戶輸入
- Document document = GetDocument(Request.QueryString["id"]);
- //我們擁有此文檔,但不能編輯它!
- if (!Locker.AcquireLock(document))
- {
- //讓我們將它添加到要查看的用戶文檔列表
- User.CurrentUser.AddDocumentToQueue(document.DocumentId);
- Response.Redirect("DocumentList.aspx");
- }
- //好了,我們擁有此文檔,并且可以編輯它
- //...
- }
關鍵行的位置是將文檔添加到當前用戶的隊列中(這會將文檔添加到會話中)。接下來,我們將創建用戶控件,該控件可以被放置到任何頁上,用于當隊列文檔可用時通知用戶。此用戶控件將包含一個 AJAX 方法以及注冊 AJAX 的類所需的代碼。
- 'VB.NET:ASP.NET AJAX示例
- Private Sub Page_Load(s As Object, e As EventArgs)
- Handles MyBase.Load
- Ajax.Utility.RegisterTypeForAjax(GetType(UnlockNotifier))
- End Sub
- '遍歷隊列文檔并檢查它們是否可用
- < Ajax.AjaxMethod()> _
- Public Function GetUnlockedDocuments() As DocumentCollection
- '獲得屬于用戶的所有隊列文檔的 ID
- Dim queuedDocument As ArrayList = User.CurrentUser.DocumentQueue
- Dim unlocked As DocumentCollection = New DocumentCollection
- For Each documentId As Integer In queuedDocumentIds
- '如果隊列文檔不再被鎖定
- If Not Locker.IsLocked(documentId) Then
- unlocked.Add(Document.GetDocumentById(documentId))
- End If
- Next
- Return unlockedDocuments
End Function現在需要的是使一些 JavaScript 發出請求并處理響應。我們將基于響應在要動態創建的表中放置已發布的文檔信息(如果有)。為此,我們將開始編寫 HTML。
- < div id="notifyBox" style="display:none;">
- < b>The following queued documents can now be edited< /b>
- < table cellpadding="5" cellspacing="0"
- border="0" style="border:1px solid #EEE;"
- id="notifyTable">
- < /table>
- < /div>
如果沒有可用的文檔(或是沒有為該用戶列出文檔),我們使用 DIV 標記隱藏所有內容,用 TABLE 標記來顯示結果。我們將使用輪詢系統來檢查是否存在任何可用的隊列文檔。一般來說,這意味著我們將在稍后一段時間內一直調用服務器端方法,并顯示結果。在加載頁面時僅發生第一次調用,每隔 X 秒發生后續調用。
- < script language="javascript">
- window.setTimeout("PollQueue();", 2000);
- //每隔 2 秒激發以檢查在具有許多用戶的實際系統中是否發布了
- //隊列文檔,2 秒可能會使服務器承受
- //過高的負荷。我們甚至可以首先檢查用戶是否
- //擁有隊列,但是我們確實需要進行一些
- //性能測試
- function PollQueue()
- {
- //UnlockNotifier 是我們使用 Ajax.NET 注冊的類型
- //GetUnlockedDocuments 是該類型中的方法,標有
- //AjaxMethod 屬性
- UnlockNotifier.GetUnlockedDocuments(PollQueue_CallBack);
- //每隔 2 秒調用其本身
- window.setTimeout("PollQueue();", 2000);
- }
- < /script>
剩下的就是處理響應。這與以前示例中的代碼相似。首先,檢查是否存在錯誤,獲得響應,遍歷可用的文檔,動態創建 HTML,在這種情況下,向表中添加行和列。
- function PollQueue_CallBack(response)
- {
- var notifyBox = document.getElementById("notifyBox");
- var notifyTable = document.getElementById("notifyTable");
- //如果我們無法找到表通知框
- if (notifyBox == null || notifyTable == null)
- {
- return;
- }
- //如果服務器端代碼出現異常
- if (response.error != null)
- {
- notifyBox.style.display = "none";
- alert(response.error); //我們應該能做得更好
- return;
- }
- var documents = response.value;
- //如果不是我們所希望的響應
- if (documents == null || typeof(documents) != "object")
- {
- notifyBox.style.display = "none";
- return;
- }
- for (var i = 0; i < notifyTable.rows.length; ++i)
- {
- notifyTable.deleteRow(i);
- }
- for(var i = 0; i < documents.length; ++i)
- {
- var row = notifyTable.insertRow(0);
- row.className = "Row" + i%2;
- var cell = row.insertCell(0);
- cell.innerHTML = documents[i].Title;
- cell = row.insertCell(1);
- var date = documents[i].Created;
- cell.innerHTML = date.getDay() + "/" + date.getMonth()
- + "/" + date.getYear();
- cell = row.insertCell(2);
- cell.innerHTML = "< a href='DocumentEdit.aspx?id="
- + documents[i].DocumentId + "'>edit< /a>";
- }
- notifyBox.style.display = "block";
- }
我們要看到的最后一個快速改進是當用戶關閉瀏覽器、導航到其他鏈接或單擊“后退”按鈕時,將自動解除文檔鎖定。通常,可以通過觸發 JavaScript OnBeforeUnLoad 事件或 OnUnload 事件達到此目的,這會打開新的小型彈出式窗口,該彈出式窗口在加載頁面時做一些清理然后自行關閉。您自己可以使用彈出式窗口,但是其他人則不能使用,它將導致彈出式窗口受阻并使文檔永久保持鎖定狀態。要解決此問題,我們仍需要兩個 JavaScript 事件,但是并不是啟動彈出式窗口,而是將通過 AJAX 執行服務器端方法。在用于編輯文檔的頁上(即,放置鎖的頁),我們添加一些簡單的 JavaScript。
- < script language="javascript">
- //如果用戶關閉瀏覽器或點擊“后退”按鈕,
- //確保該文檔會被解除鎖定
- window.onbeforeunload = ReleaseLock;
- function ReleaseLock() {
- Locker.ReleaseDocument(< %=DocumentID%>);
- }
- < /script>
在這里,DocumentId 是在后面的代碼中定義和設置的變量。另外,我們可以在會話中存儲 DocumentId,并在服務器端 ReleaseDocument 中訪問。通常,ReleaseDocument 從鎖定的文檔列表中刪除文檔。
以上就是ASP.NET AJAX示例:文檔鎖定程序的實現。
【編輯推薦】