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