摘要了解如何規劃和設計 ASPNET 應用程序本文以一個知識庫 Web 應用程序為例討論實際應用程序創建實踐中最常見的幾個因素
簡介
這是一個系列文章在這個系列文章中我們將逐步詳細介紹如何使用 Microsoft ASPNET 和 Microsoft Visual StudioNET 來設計實現和部署典型的 Web 應用程序以探討實際應用程序創建實踐中最常見的幾個因素我們不僅僅布置一些 Web 窗體也不局限於只對後端數據庫進行一些數據綁定數據綁定和 Web 窗體布局很重要但是有許多其他問題也非常重要
例如無論采用何種目標平台或語言所有經過良好編碼的項目都包括一些基本的規劃步驟例如目標聲明用戶方案文檔甚至用於標識解決方案的物理邊界和邏輯邊界的體系結構文檔此外在解決方案生命周期的早期就將安全規劃包含在內是一種非常好的習慣這些內容與良好的數據庫模型精心設計的中間件組件以及簡潔的用戶界面設計一起可以確保您最終在生產中部署的應用程序是安全的可靠的並且是用戶友好的
此時一些讀者可能會認為本文屬於那些基調很高的文章目標定位在某些超大型企業級方案而這種方案根本不適用於一般的小工廠愛好者或個人開發團體其實並不是這樣!即使只是創建您自己個人使用的基於 Web 的小型解決方案從一開始就進行完善的規劃將有助於確保流程最終的輕松實現和部署而且並不是高級的程序員或 Web 開發人員才可以使用這些技術無論您的技術水平如何也無論您屬於哪類目標讀者我相信您都會發現這一系列文章對您很有幫助它為您提供了豐富的信息而且(請允許我這樣說)十分有趣
我們將生成一個稱為 DotNetKB 的示例知識庫 Web 應用程序這個過程將貫穿整個系列文章在作為第一篇文章的本文中我們將介紹典型項目的設計階段包括基本規劃應用程序體系結構和實現方案設計學習完本文後您將已經准備好所有的文檔並會迫不及待地希望開始創建解決方案
預備工作非常簡單我們跳過這部分內容直接開始第一步應用程序規劃
規劃基本 ASPNET 應用程序
使用 Visual Studio NET 創建基於 Web 的 ASPNET 應用程序的第一步是制定基本的應用程序規劃 (AP)制定規劃不僅對於由多個開發人員建立的大型解決方案而言是必不可少的而且即使對於最小的應用程序一個完善的 AP 也是非常重要的創建 AP 有助於您在開始編碼之前就能仔細考慮一些常見問題這樣您可以在應用程序生命周期的早期便完全了解挑戰和解決方案而不是在完全陷入窘境之後才發現問題在《Software Project Survival Guide》一書中作者 Steve McConnell 指出在軟件項目後期糾正錯誤所花的成本與在早期階段發現並糾正這些錯誤所花的成本相比前者可能是後者的 倍
一個完善的項目規劃包含哪些內容?可以包含許多內容但最基本的是要包含目標聲明和一系列用戶方案還有其他很多有用的資料包括需求文檔編碼標准交付進度測試過程等對於我們要建立的簡單示例解決方案將主要介紹簡單的應用程序聲明和一些用戶方案同時還將解決一些其他問題
應用程序聲明
此系列文章要建立的項目(稱為 DotNetKB)是一個簡單的知識庫 Web 站點在這個站點中用戶可以提各種問題並可以得到授權專家的回答這樣以後訪問者在查找常見 ASPNET 問題的解決方案時可以對得到的結果數據進行搜索和過濾
這是對我們的 DotNetKB 項目的一個基本目標聲明DotNetKB 是一個基於 Web 的應用程序它可以列出訪問者提出的一系列問題並顯示授權專家對這些問題作出的回復訪問者可以向系統添加新問題並可以按照問題的主題問題和/或回答中的關鍵字來搜索和過濾這些問題訪問者還可以按主題或按添加到系統中的日期來對問題列表進行排序
授權專家可以登錄到應用程序中已設置安全機制的部分審閱問題添加編輯和刪除對一個問題的一個或多個回答應用程序管理員還可以建立專家登錄權限和登錄配置文件以及添加編輯和刪除問題主題
此外還提供了一些基本統計信息包括系統中問題和回答的數量以及每個專家的回復數量和至今已被訪問的頁面數量
正如您從上面的聲明中看到的那樣該解決方案非常簡單在閱讀目標聲明時您可能會開始考慮可以添加到這個應用程序的許多其他功能以使應用程序更加強大這說明了項目目標聲明的一個主要依據即避免功能蔓延我們都清楚如果更改最終結果本來基於的概念簡單的想法將導致非常龐大且歪曲的結果有句老格言如果不知道要去往何方你可能會在某個地方停下來它原本揭示的是夏季公路旅行其道理同樣可用於軟件項目
一些項目的目標聲明中可能需要包含更多的信息而對於我們的使用上面的目標聲明就符合要求現在我們對於要完成的應用程序有了一個清晰的認識接下來需要一些詳細的信息來描述用戶如何與系統交互以及用戶需要執行哪些任務來完成目標我們需要一系列用戶方案
文檔化用戶方案
用戶方案沒有什麼令人驚異之處通常它們只是描述用戶如何與應用程序交互用戶方案的關鍵價值在於記錄了關於每個人對用戶希望系統如何運行以及應用程序應如何響應的設想通過完成這個過程您將可以完全了解處理各種用戶與系統的交互時所需的數據點和函數換句話說編寫完善的用戶方案將有助於您確定完成解決方案需要實現的數據庫中間件和用戶界面元素
注意Visual Studio NET Enterprise Architect 有一項非常不錯的功能即允許您使用 Microsoft Visio? 通過 UML(統一建模語言)創建用戶方案然後生成這些方案的基本代碼在這裡我不打算深入探討這些細節但是您可以在 MSDN? Academic Alliance 站點找到一篇關於這一主題的好文章 Generating NET Code Using Visio Enterprise Architects UML作者是 Sreedhar Koganti
有了上一節的目標聲明後下面是 DotNetKB 項目的幾個示例用戶方案
搜索知識庫
匿名用戶可以輸入一個或多個關鍵字並執行搜索搜索將返回包含這些關鍵字的問題和/或回答列表用戶可以將關鍵字搜索鎖定在僅搜索問題僅搜索回答或者二者都搜索返回的列表將顯示問題及其回復數和被其他用戶訪問的次數單擊鏈接將返回以時間先後逆序排列的回復(純文本)列表
將新問題輸入到知識庫中
匿名用戶可以浏覽用於向數據庫輸入新問題以供授權專家審閱和回復的屏幕用戶可以輸入問題的標題和內容並可以選擇在一系列主題中的某個主題下記錄該問題用戶還可以輸入他們的名字和相關的 URL(電子郵件Web 地址等)輸入將被驗證以確保包含必需的數據並確保所有輸入數據不會受到腳本攻擊等一旦數據經過驗證並被保存到數據庫中用戶將看到一個響應屏幕感謝用戶的支持並將用戶直接連接到主頁此外用戶還可以選擇讓該站點記住他們的姓名和 URL 以備以後訪問該站點時使用
您已經了解它的工作原理了對嗎?每一個方案都嘗試細化用戶交互的重要方面例如上面列出的兩個方案表明用戶為anonymous(匿名用戶)這表示這類用戶不需要登錄或進行其他方式的授權第二個示例還標識了若干輸入值驗證步驟和可選操作
當然這只是兩個示例完整的系統需要更多的方案此外需要特別注意的是用戶不僅僅可以是人也可以是您的程序需要與其通信的其他應用程序甚至還可以是您的應用程序的其他部分例如一個方案描述主頁如何列出最近添加到知識庫中的內容以供任何人查看此例中的用戶將是主頁自身還有一些方案描述專家如何查找和回復新問題以及管理員如何更新主題列表並管理系統的其他部分我已為討論這個簡單的應用程序標識了 多種方案您可以在 DotNetKB 中找到當前列表(以及與此項目相關的所有其他資料)
至此我們就有了目標聲明和一些用戶方案現在是時候稍憩一下然後學學一些技術了我們需要定義應用程序體系結構這可以幫助我們以鮮活有效的代碼實際實現方案
定義應用程序體系結構
有了基本的目的和為解決方案開發的用戶方案列表後您需要開始籌劃整體的體系結構主要目標是標識應用程序的邏輯方面和物理方面即如何將應用程序拆分為各種有用的部分在本節中還添加了安全性方面的內容安全是在規劃的一開始您就需要考慮的問題而不是在開發周期中最後添加的內容我們稍後會在本節中詳細討論這個問題
邏輯體系結構
從邏輯上講您需要規劃解決方案以標識數據存儲數據訪問業務規則用戶界面等之間的邊界通常Web 開發人員會選擇一個兩階段模型並用 Web 窗體存儲用於訪問現有數據存儲系統(例如 Microsoft SQL Server)的所有代碼一個更有效的方法是創建一個位於 Web 窗體用戶界面與 SQL Server 數據存儲系統之間的中間層組件庫這種三層方法(Web 窗體組件數據庫)通常是大多數應用程序所需的但是在某些情況下可能需要一個其他層來處理服務器之間傳輸的數據這個傳輸層可以使用獨立於平台的協議(例如 XMLSOAP)來實現但是如果您從頭到尾都使用 Microsoft NET 技術則可以使用 NET 遠程協議的二進制版來完成這一任務而且速度比使用 XMLSOAP 要快得多
對於我們的示例我們將定義三個邏輯邊界用戶界面(Web 窗體)中間層(一個 NET 組件程序集)和數據層(SQL Server 數據庫)圖 顯示了如何表示這一內容
圖 三層圖
現在我們有一個簡單的邏輯模型它是如何起作用的?它有助於我們考慮各個邏輯組之間的邊界每個邏輯層應盡量與其他層獨立理想的情況是圖層中的更改應該對整體產生最小的影響例如如果將數據存儲從 SQL Server 更改到 XML 數據文件唯一受到影響的圖層應是中間層圖層用戶界面應該根本無需考慮更改這會使您進行思考如何實現解決方案的實際編碼以實現此原則
另外邏輯層有助於我們考慮安全問題各個圖層之間的邊界都存在潛在的安全漏洞而且各個圖層可能有自己特定的安全措施(SQL Server 權限NET 運行時權限ASPNET 安全等)同樣我們稍後會在本節中詳細討論這個問題
物理體系結構
確定邏輯層後考慮物理層也很重要例如您可以在同時安裝有 SQL ServerInternet Information ServerASPNET 和 NET 運行時的單個實際計算機上實現這個應用程序這將是一個物理層但更可靠且可擴展的方法是在由三個 Web 服務器組成的簇上部署 Web 窗體在兩個應用服務器上部署 NET 組件程序集在兩個故障恢復模式的 SQL Server 上部署數據庫這樣產生的物理體系結構將七個 Windows 服務器包含在三個主要組中Web 簇組件簇和數據庫簇如果您了解系統的不同邏輯部件可以位於不同的計算機上您可能會實現不同的代碼
對於我們的示例我們采用一個有效且強大的兩層模型Web 服務器托管用戶界面和組件數據庫服務器托管 SQL Server 數據存儲如果通信量非常大這個模型使我們可以靈活地在簇中添加更多的服務器並使其保持足夠的簡潔以便於處理下面的圖像顯示了此物理體系結構與前面定義的邏輯體系結構之間的映射關系
圖 物理體系結構與三層體系結構之間的映射關系
正如您看到的那樣邏輯體系結構和物理體系結構不必相同在規劃階段還要考慮一項內容安全
安全規劃
Microsoft 有一個關於安全性與軟件這一主題的歌訣Secure by design secure by default and secure by deployment(設計安全默認安全和部署安全)即在安全中設計期待系統在默認情況下是安全的以及創建可以在安全環境中成功部署的解決方案安全始終是重要的既然越來越多的軟件要在公用的 Internet 上生存編寫安全的軟件就更加關鍵對於我們而言幸運的是NET 運行時和 Windows 操作系統提供廣泛的安全選項和功能我們可以輕松地將其包含在我們的應用程序中無需過分注重標識和消除聯機解決方案中安全漏洞的細節我們可以指出其中一些最常見的漏洞並指出我們的應用程序規劃如何進行處理
注意有關可用選項的詳細信息請參閱 Microsoft Security Developer Center
緩沖區溢出
這可能是已編譯應用程序中最常見的安全漏洞由於我們將使用 NET 運行時而它是設計用來在內存中安全運行的因此不太可能發生緩沖區溢出此外我們使用 Microsoft Visual Basic? NET 對解決方案進行編碼而 Microsoft Visual Basic? NET 不像 C 或 C++ 那樣容易受到緩沖區溢出問題的影響但是即使我們打算用 C++ 創建組件我們還可以使用編譯程序的特殊功能GS 轉換來保護我們免受大多數緩沖區溢出的攻擊
數據庫攻擊
另一種常見的安全漏洞可能會使惡意用戶獲得訪問存儲在數據庫中的原始數據的權限為了防止黑客獲得數據的控制權我們僅使用 SQL Server 存儲過程而不使用內聯查詢這樣可以大大減少試圖在輸入流中插入其他 SQL 命令的攻擊我們還在程序中多個位置處使用輸入驗證以確保所有輸入僅包含有效的字符
交叉站點腳本攻擊
對 Web 應用程序進行的常見攻擊還有一種它涉及到用戶在輸入流中添加客戶方腳本這類攻擊將執行附加的對話並誘騙用戶將個人數據發送到黑客自己的 Web 站點要解決這個問題我們使用 ASPNET 的一個新功能過濾出這種惡意代碼的所有輸入防止將它置入系統中顯示屏幕上還包含附加代碼它將自動禁用任何腳本或顯示可能會插入到數據存儲中的標記
至此我們已獲得了應用程序的邏輯模型和物理模型以及確保實現方案包含的安全功能清單擁有了這些以及目標聲明和用戶方案我們可以開始這次編碼前探險的最後一部分了
完成設計文檔
在直接進入項目的編碼部分之前需要花一點時間實際勾畫出應用程序的邏輯組件這非常重要在我們的示例解決方案中我們要實現解決方案的三個邏輯組件數據庫NET 數據訪問組件和 ASPNET 用戶界面在下面幾篇文章中我們將非常詳細地介紹如何實現這些組件但現在我們只是勾畫出每個組件的大致輪廓討論過程中最重要的方面即文檔化組件間的交互
數據庫
對於 DotNetKB 應用程序我們需要將數據存儲在三張表中主題問題和回答(請參閱下圖)
圖 主題問題和回答表
我們需要使用存儲過程以使中間層組件也可以安全地訪問數據有關數據庫的細節我們將在下一篇文章中討論這裡我們只是指出列出表名稱及所有列細節默認索引和存儲過程列表的數據庫文檔應該包含在一個完整的數據庫設計文檔中即文檔中應該具有成功實現系統數據存儲部分所需的詳細信息
注意如果留心的話您可能會注意到我們未提及將專家數據存儲在數據庫中只是為了使項目更加有趣(同時給我們一個機會使用直接 XML 數據存儲)我們將專家信息存儲在一個 XML 數據文件中
數據訪問組件
數據訪問組件設計文檔描繪與數據存儲系統的交互以及與用戶界面的交互的所有細節在有些系統中數據訪問組件實際上是處理過程中各種問題的多個程序集例如可能會有一系列業務規則呈現在與數據存儲和檢索完全獨立的用戶界面上在這種情況下將業務組件與數據訪問組件分開實現可能比較明智
在我們的示例中實際實現的是兩個單獨的組件Message 組件和 DataAccess 組件如果在支持基於 XML 的數據的傳輸服務(例如 SOAP Web Service)中進行規劃這種面向消息的實現方案將會特別有成效
消息組件
消息組件定義一系列用於在各圖層之間傳輸數據的類這些消息可以作為二進制或 XML 文本數據存在消息圖層的價值在於保護系統的其余部分使其獨立於數據存儲實現方案的具體細節例如 SQL ServerXML 文件等此外通過實現消息圖層而不是更復雜的智能對象庫我們的解決方案可以更輕松地支持那些不能同時發送數據和類級別邏輯的遠程調用服務例如 XMLSOAP
下面是一個消息類示例在該示例中實現了 Topic 消息及其集合
Public Class Topic
Private _ID As Integer
Private _Title As String
Private _Description As String
Public Property ID() As Integer
Get
Return _ID
End Get
Set(ByVal Value As Integer)
_ID = Value
End Set
End Property
Public Property Title() As String
Get
Return _Title
End Get
Set(ByVal Value As String)
_Title = Value
End Set
End Property
Public Property Description() As String
Get
Return _Description
End Get
Set(ByVal Value As String)
_Description = Value
End Set
End Property
End Class
Public Class Topics
Inherits SystemCollectionsCollectionBase
Default Public Property Item(ByVal index As Integer) As Topic
Get
Return CType(List(index) Topic)
End Get
Set(ByVal Value As Topic)
List(index) = Value
End Set
End Property
Public Function Add(ByVal s As Topic) As Integer
Return ListAdd(s)
End Function
Public Sub Remove(ByVal index As Integer)
ListRemove(index)
End Sub
End Class
注意如果您已嘗試過面向消息的設計便會了解我們想要使這些消息類系列化以便在應用程序圖層之間輕松地來回發送幸運的是NET 運行時知道如何進行這項操作而無需我們做過多的工作但是當我們學習創建消息的文章時我們將詳細討論 NET 運行時如何系列化類以及我們如何進行操作以使代碼中的過程最優化
在後面實現消息組件和數據訪問組件時文章中將介紹此方法的細節設計文檔將包含一個由所有信息及其屬性與數據類型組成的列表現在我們只是考慮如何使用此消息方法來封裝圖層間的數據傳輸如何創建一種與本地方案和遠程方案配合使用的常規數據服務
數據訪問組件
定義消息類的概念後數據訪問組件可以集中精力處理與數據存儲系統直接對話的細節並以正確的消息格式返回信息在我們的示例中這將涉及到使用來自用戶界面的請求映射 SQL Server 存儲過程並創建可返回到用戶界面進行顯示的消息(或消息集合)
例如下面是一個數據訪問組件的一部分示例代碼該組件將從數據存儲中檢索單個 Topic 記錄並將正確的消息格式返回到用戶界面
Public Function GetTopicRecord(ByVal ID As Integer) As MessagesTopic
Dim t As MessagesTopic = New MessagesTopic
cn = New SqlConnection(secureConnectionString)
cd = New SqlCommand(GetTopic cn)
cdCommandType = CommandTypeStoredProcedure
cdParametersAdd(@ID ID)
cnOpen()
dr = cdExecuteReader()
drRead()
With t
ID = ID
Title = dr(Title)
Description = dr(Description)
End With
Return t
End Function
設計文檔將包括一系列用於處理來自用戶界面的各個請求的類和方法並含有有關調用哪個存儲過程以及返回何種消息格式的詳細信息同樣我們將在後面主要介紹數據訪問圖層的文章中討論此過程的細節
Web 用戶界面
最後用戶界面設計文檔將包括完成各種方案所需的所有用戶輸入和顯示通常來說用戶界面文檔包括界面機制的細節以及使用戶界面呈現唯一性的圖形設計元素例如配色方案字體和總體頁面設計與用於獲取搜索查詢的正確數據的輸入名稱和輸入數量一樣重要
要使文檔簡潔通常在一個與圖形設計單獨的文檔中概要描述機制細節這是我們將要在示例中做的工作在後面的一篇文章中我們將創建一個綜合性用戶界面文檔和實現方案詳細說明每個屏幕的元素和相關操作在另一篇文章中我們將處理應用程序有關圖形的各個方面重點討論作為一種外觀服務的級聯樣式表的使用
下面是一個典型的用戶界面描述它涉及主題編輯方案
主題輸入屏幕
主題屏幕將顯示所有當前主題(主題 ID 和主題名稱)的一個縮略列表在每個主題旁邊還將顯示一個編輯鏈接單擊編輯鏈接將會調用關聯的主題記錄並將其顯示在一系列的輸入框中標題和描述是可編輯的而主題 ID是只讀的用戶可以編輯標題和描述然後按保存按鈕將更改寫入數據存儲輸入將被驗證兩者都是必需的輸入項標題的長度限制為 個字符描述的長度限制為 個字符更新完成後將顯示一條響應消息指出已確認更新如果更新失敗則顯示一條消息指出錯誤狀況
用戶還可以刪除現有的主題記錄方法是單擊列表中的編輯鏈接審核顯示屏幕上的記錄細節後單擊刪除鏈接刪除完成後將顯示一條響應消息指出已確認更新如果更新失敗則顯示一條消息指出錯誤狀況請注意用戶不能刪除與現有問題或回答相關聯的主題
此外用戶可以完整地添加新主題記錄方法是在初始顯示屏幕上單擊新建主題鏈接將顯示標題和描述輸入(不顯示 ID 輸入)並提供一個保存按鈕輸入將被驗證兩者都是必需的輸入項標題的長度限制為 個字符描述的長度限制為 個字符更新完成後將顯示一條響應消息指出已確認更新如果更新失敗則顯示一條消息指出錯誤狀況
利用上面的敘述您可以輕松地實現一個完整的功能屏幕判斷一個好的設計文檔的方法是它能夠使讀者完成工作且不會提出額外的問題最終的用戶界面設計文檔將包括應用程序中每個屏幕的此類敘述
小結並付諸行動
我們簡要介紹了數據庫中間層和用戶界面實現方案的最終設計文檔加上體系結構和初始規劃文檔它們形成了我們的完整設計包在實際的情況中即使是最小的系統完成這些文檔也至少需要幾個小時對於大型系統可能需要幾周甚至可能幾個月的時間有些人可能會對此有一點挫敗感但是通過事先完成這些工作您可以在進入項目的編碼階段之前很早就了解完成解決方案面臨的幾乎所有主要障礙這樣可以減少編寫實際代碼的時間並且還可以減少您會遇到的錯誤和障礙的數量
在下一篇文章中我們將討論使用 Visual Studio NET 在 SQL Server 中建立數據存儲系統的有關細節我們將定義數據表創建必需的存儲過程並設置正確的數據訪問以確保任何組件和數據本身之間具有安全可靠的連接
From:http://tw.wingwit.com/Article/program/net/201311/15395.html