在我的第一篇部落格中,我發布過一個樣本項目,
主要示範了我的我的AJAX架構和我的通用資料訪問層。
雖然在當初我認為我已考慮地比較周全了,而且還提供了足夠的說明文檔,
但在發布後的將近一年的時間裡,還是有不少人給我發郵件,問我一些關於不能運行樣本的問題。
在所有問題中,主要集中在IIS和SQL SERVER的配置方面。
因此,我認為還是有必要再來談一下在IIS6/7以及SQL SERVER中部署ASP.NET網站的過程了。
在上篇部落格【寫自己的ASP.NET MVC架構(下)】中,
我又發布了一個樣本項目,它也包含一個網站項目,今天的介紹過程將主要以這個樣本為主。
對於以前的樣本所需配置的相同部分將不會重複介紹,不同點則會額外補充。
查看web.config檔案
ASP.NET網站與一般的傳統型程式不同,不是拷貝過來就能啟動並執行(資料庫連接除外)。
要想運行它,通常需要一些配置過程。
但是,我們到底需要配置什麼呢?
答案是:查看web.config
web.config通常會放在網站的根目錄,這個檔案中包含了一最重要的網站運行參數。比如:
connectionStrings,httpHandlers,httpModules ,這些參數都是網站開發人員認為運行網站所必要參數。
因此,如果我們想將一個網站部署到IIS中,必須首先開啟web.config檔案,逐個確認這些重要的參數是否符合要求。
這裡要補充一點的是:有些開發人員喜歡將各類參數放在appSettings配置節中,即便是資料庫的連接字串也放在appSettings中。
我只能說:這是個很不好的習慣。因此,在部署這類網站時,可能還要注意一下appSettings是否包含資料庫的連接字串,
這就需要人工識別了。當然了,appSettings中還可能包含一些重要目錄配置,同樣,也只能人工識別了。
今天要講述的參數主要涉及到IIS和SQL SERVER,因此本文將會分開介紹它們。
而且IIS還會分為6和7.5二個版本來單獨示範。
SQL SERVER則以 2005 Express版本來示範。
我示範所用的作業系統為:Windows Server 2003和Windows 7 ,它們分別附帶了IIS 6和IIS 7.5
說明:通常我們在部署網站時,都應該先根據web.config定義的那些重要參數來配置網站。
但為了讓您能對這些參數有較深刻的印象,下面的示範中,不是先根據web.config來配置網站,
而是採用【從建立一個網站後,一步一步地發現問題並解決】的方式來講解這個過程。
在IIS中建立網站
每個ASP.NET程式都是一個網站,要想運行它們,都需要在IIS中部署它們,
部署的第一步就是要在IIS建立一個網站。
在IIS中建立網站的過程比較簡單,因為IIS都提供嚮導介面來協助我們完成這個配置過程,
因此,本文打算省略那些無意義的貼圖。
說明,我們先從IIS6開始。
這裡只要求您在IIS中建立一個網站,把它配置成網站就可以了,其它的配置我們後面再談。
樣本項目:點擊此處進入 MyMVC DEMO 下載頁面
網站建立好了嗎?我停下來等一下吧。
我的網站配置好了,現在已經可以用瀏覽器訪問它。
現在我們可以切換風格來試試效果,點擊頁面右上方的【3】試試看。
噢,怎麼一開始就出錯了:
看到這個提示,不要茫然。為了介面友好,我用JavaScript捕獲了這個錯誤,但現在我們需要知道錯誤的原因是什麼,怎麼辦呢?
有FireBug或者Fiddler2嗎?
如果有,就開啟它們吧。是我用FireBug看到的錯誤原因(需要重新執行剛才的操作):
從FireBug中,我們可以看到,剛才的操作觸發了一次請求,請求的地址是:/AjaxStyle/SetStyle.cspx
cspx是個什麼副檔名呢?還是開啟web.config看一下吧。
<httpHandlers> <add path="*.cspx" verb="*" type="MyMVC.AjaxHandlerFactory, MyMVC" validate="true" /> <add path="*.aspx" verb="*" type="MyMVC.MvcPageHandlerFactory, MyMVC" validate="true" /> <add path="/mvc/*" verb="*" type="MyMVC.MvcPageHandlerFactory, MyMVC" validate="true" /></httpHandlers>
在web.config中,網站要求配置的一些httpHandlers中,第一個便是針對【cspx】副檔名的。
這裡我要解釋一下【cspx】這個副檔名了。在以前的樣本中,我選擇了【cs】這個副檔名表示一個AJAX調用,
但是,後來發現很多人在IIS中部署中遇到問題了(原因後面再說)。於是,這次我換了個副檔名。
然而,又有人問我:cspx, 是不是寫錯了? 或許他認為應該是【aspx】才對。
這個問題我用郵件回答過多次了,今天用部落格的形式再回答一次:
取什麼副檔名都不重要,我只要選擇沒有用過的副檔名來區分是AJAX調用就可以了。
我也可以取【fish】來做為AJAX請求地址的副檔名,只是擔心一些人認為俗氣而已。
IIS6 添加副檔名映射
回到IIS,在網站節點上,右擊,從彈出的菜單中,選擇【屬性】,然後在彈出的對話方塊中,選擇【主目錄】選項卡,並點擊【配置】按鈕。
此時的介面應該是這樣的:
找到【ascx】這個副檔名,雙擊它,是不是彈出下面這個對話方塊?
照著圖片的操作去完成:複製【可執行檔】的設定路徑。然後點擊【取消】關閉對話方塊。
此時將回到【應用程式配置】對話方塊,點擊【添加...】按鈕,
照著圖片操作吧。對話方塊中的【可執行檔】的參數,此時已在Windows剪下板中,現在只要粘貼就可以了。
全部【確定】,關閉所有對話方塊,再回到瀏覽器,然後再試一次。
現在可以操作了吧?
先不要點擊其它連結,還是來對剛才的操作做個小結吧。
在ASP.NET中,有時候我們可能會需要建立自己所需的HttpHandler來處理一些特殊的請求。
我的MyMVC架構就有這個需求:將AJAX請求與頁面的請求分開來處理。
所以我們需要一些特殊格式的URL。通常選擇一個沒用過的副檔名會比較方便,因此我選擇了 cspx
為了能告訴ASP.NET將以下格式的ULR映射到AjaxHandlerFactory
/Fish.AA.AjaxTest/Add.cspx/Fish.BB.AjaxTest.Add.cspx/Fish/BB/AjaxTest/Add.cspx/AjaxDemo/GetMd5.cspx/AjaxDemo.GetMd5.cspx
我就需要在web.config中註冊這種URL模式,並且為了能最好的匹配這些URL,我可以使用下面的配置:
<httpHandlers> <add path="*Ajax*/*.cspx,*Ajax*.*.cspx" verb="*" type="MyMVC.AjaxHandlerFactory, MyMVC" validate="true"/></httpHandlers>
我們可以用Visual Studio內建的WebDev.WebServer.EXE來運行網站程式。
本來,這一切都是很完美的。
可是,IIS中並不支援這麼複雜的path設定,它只能支援簡單的副檔名映射。
所以,我也只好使用簡單的副檔名:【.cspx】來向IIS註冊。
我再來解釋一下,為什麼在ASP.NET中,前面那個path能夠識別我上面所說的5種格式的URL?
在ASP.NET管線的處理器映射階段,ASP.NET會將【*Ajax*/*.cspx,*Ajax*.*.cspx】轉換成下面的Regex,
再來檢查每個請求的URL是否匹配。
(?:\A|(?<=/))[^/]*Ajax[^/]*/[^/]*\.cspx\z|(?:\A|(?<=/))[^/]*Ajax[^/]*\.[^/]*\.cspx\z
有興趣的話,您也可以檢驗一下,這個Regex與前面的URL都能匹配。
從這裡也可以看出ASP.NET對處理器的映射實現,是可以支援比較複雜的URL模式的。
關於處理器的映射過程可以參考我的部落格【細說 HttpHandler 的映射過程】
前面解釋了我為什麼最終選擇【.cspx】來向IIS註冊處理器了。
在註冊時,還有二個參數也比較重要:
1. 可執行檔:其實就是一個實現了ISAPI的模組,IIS會將匹配的請求交給它,然後由它再交給ASP.NET。
這個參數的路徑比較長,我們根本不需要記住它,只需要找個已有配置中,將它COPY出來就可以了。
2. 確認檔案是否存在:這個參數一定不要選擇。因為我們請求的URL並沒有對應的檔案存在。
這裡要補充一點:
我以前發布的FishWebLib DEMO中,
使用了【cc】這樣的副檔名,可以按照上面的方法註冊。
但我還使用了【cs】和【ascx】這二個副檔名。由於這二個副檔名的註冊已經存在了,
所以,我需要修改它們的配置:雙擊配置項,確保不要勾選【確認檔案是否存在】即可。
IIS6 無副檔名的映射
讓我們再回到前面已配置好的樣本中,此時頁面的顯示應該是這個樣子的:
點擊一下頁面上的連結【/mvc/Customers】試試。
不要以為我是在故意設定陷阱哦。我在設計樣本程式時,根本也沒想到會這樣。
到這裡,可能有人會想,在httpHandlers中不是還有個【path="/mvc/*"】沒有配置嗎?
繼續按照前面的方法去配置就能解決問題了。
好吧,我再照著前面的方法再試著註冊【path="/mvc/*"】試試,結果如下:
因此,前面的方法對於這類【無副檔名】的URL來說,是無效的。
對於這類無副檔名的URL,在IIS6中可以使用添加【萬用字元應用程式對應】的方法來解決。
回到【應用程式配置】對話方塊,點擊【插入...】按鈕,彈出下面的對話方塊:
按照圖片來設定一下吧。然後,【確定】關閉對話方塊。此時的設定應該是這樣的:
全部點擊【確定】關閉所有對話方塊。
讓我們再次回到樣本程式,此時可以發現,什麼問題都沒有了。
再補充一句:如果使用這種方法,前面註冊cspx的過程就不需要了。因為此時所有的請求都會交給ASP.NET,而ASP.NET會識別我在web.config中所做的配置。
目錄的寫入許可權
為了方便MyMVC DEMO的部署過程,
這次我選擇了XML檔案做為資料來源。寫入XML的時機是在ASP.NET被停止啟動並執行時候(Application_End事件中)。
讓一個在IIS中啟動並執行網站停止啟動並執行方法就是停止網站所使用的【應用程式集區】。
可以在網站屬性對話方塊中找到網站所使用的【應用程式集區】:
再切到IIS的【應用程式集區】的列表,找到前面那個【應用程式集區】,右擊滑鼠,
從彈出的菜單中點擊【屬性】菜單,然後在出現的對話方塊中選擇【標識】選項卡:
從這個圖片中,我們可以知道網站以哪個Windows帳號在運行。記住這裡,後面會用到。
好吧,點擊【取消】關閉對話方塊。
補充一點:要想知道網站以什麼帳號運行,還可以查看【Windows工作管理員】,
找到w3wp.exe所在進程即可:
回到樣本程式中,我們可以隨便添加一些資料。
然後,在【應用程式集區】列表中,停止網站所使用的應用程式集區。再啟動它。
重新重新整理樣本程式的頁面。
發現什麼了?是不是資料沒有儲存下來?
如果探索資料沒有儲存起來,可以繼續閱讀。
資料不能儲存的原因並不是因為代碼沒有執行,而是因為,網站啟動並執行帳號沒有許可權寫資料檔案。
XML是放在網站的App_Data目錄中,為了檢查網站是否有寫入許可權,可以在App_Data目錄上右擊,
然後選擇【屬性】菜單,切換到【安全】選項卡:
經過前面的分析,我們已經知道網站是以【NETWORK SERVICE】帳號運行,
然而,在這個目錄的安全設定中,並沒有允許【NETWORK SERVICE】帳號能有寫入許可權,
所以,網站在停止運行時,是由於沒有許可權才導致不能儲存資料的。
此時,我們可以賦予【NETWORK SERVICE】帳號對App_Data目錄有寫入許可權。
設定如:
好了,您可以再去重啟網站所在的【應用程式集區】,會發現現在資料能正常儲存了。
SQL SERVER的配置
在FishWebLib DEMO中,
我為了示範我的通用資料訪問層而引入了SQL SERVER,
因此,樣本程式需要SQL SERVER的支援。
首先,還是回到web.config,來看一下樣本程式需要訪問什麼樣的資料庫:
注意:樣本程式需要串連的SQL SERVER伺服器是:localhost\sqlexpress
我的機器上安裝了三個SQL SERVER的執行個體:
因此,我需要以【具名執行個體】的方式來訪問。
如果您的機器將SQL SERVER做為【預設執行個體】來安裝,則需要修改為:localhost
在樣本的壓縮包中,我提供了SQL SERVER所需的資料檔案:db\MyNorthwind.mdf
在運行樣本前,我需要將它【附加】到SQL SERVER中。
現在需要先啟動 SQL Server Management Studio ,串連SQL SERVER的執行個體後,
在【物件總管】的樹型控制項中,找到【資料庫】節點,右擊,然後點擊【附加...】菜單,
在出現的對話方塊中,點擊【添加...】按鈕,選擇MyNorthwind.mdf檔案,然後點擊【確定】按鈕。
我這邊出錯了。
再仔細地看一下,發現是記錄檔沒有找到造成的。
是的,我並沒將記錄檔也放在壓縮包中。
好吧,在對話方塊中刪除記錄檔就可以了,再次【確定】。
還是出錯:
注意了:這次的錯誤與前面的錯誤並不一樣。
這次是說沒有目錄的寫入許可權。
當遇到沒有目錄的存取權限時,我們首先要知道程式是以什麼帳號在運行。
這是非常重要的。要不然,如何配置目錄的存取權限呢?
判斷程式以什麼帳號運行最簡單方法就是:開啟【Windows工作管理員】,然後去找進程。
這個方法可參考前面的過程。最終我們可以發現sqlserver.exe是以【NETWORK SERVICE】帳號在運行(我的機器是這樣)。
好吧,再按照前面設定App_Data目錄許可權的方法再設定MyNorthwind.mdf檔案所在目錄的存取權限。
再次嘗試【附加】資料庫,將能成功完成。
在我機器上,現在已經可以運行樣本程式了。
說明:如果由於種種原因,不使用【Integrated Security=SSPI】的串連認證方式,還可以使用【使用者名稱/密碼】的方式,
那就需要修改web.config中的連接字串了。
小結:
1. 由於SQL SERVER的資料檔案儲存在Windows作業系統中,因此必須授予運行SQL SERVER進程的帳號所必需的目錄存取權限。
2. 串連到SQL SERVER時,也可能會因為SQL SERVER驗證串連身份而失敗,那麼也必須配置需要的存取權限。
到此為止,樣本所需的IIS配置以及SQL SERVER的配置都介紹完了。
在IIS7中部署ASP.NET程式
前面介紹了如何在IIS6中部署一個ASP.NET網站,現來看一下在IIS7.5中如何完成這個過程。
接下來的示範將以Windows 7的IIS7.5為準。
IIS7.5相對於IIS6的改進,給我的感覺是:部署ASP.NET網站簡直太容易了。
IIS7為了相容老版本,它支援二種模式來運行ASP.NET程式:整合模式,傳統模式。
所謂的傳統模式,其實就是為了相容IIS6的模式。下文將著重介紹整合模式,這樣才能體現IIS改進的優勢。
在IIS6中,我們需要配置副檔名的映射或者萬用字元映射,將請求交給一個ISAPI篩選器,然後由它再交給ASP.NET,
最終由ASP.NET再將請求交給我們的httpHandlers, httpModules。
我們在web.config中配置的httpHandlers, httpModules,對於IIS6來說是不可見的,所以,只能再次到IIS中配置。
從IIS7開始,IIS支援以一種稱為【整合模式】的方式運行ASP.NET程式,此時,IIS能直接將請求交給ASP.NET的httpHandlers和httpModules,
而且還可以直接從web.config中直接讀取配置,因此,只要我們把web.config準備好,配置任務就非常簡單了。
由於這個緣故,我在後來提供的樣本中,在web.config中已增加對IIS7的支援。
以下就是二個樣本項目所需的IIS7的配置部分。
FishWebLib DEMO只需要下面的配置就可以了:
MyMVC DEMO所需的配置如下:
以上這些配置會反映在IIS7.5的哪些地方看到呢?
請看:
在這個【處理器映射】列表中,前三個不正是我在web.config中的配置嘛。
前面還有一塊fileExtensions的配置又是做什麼的呢?
請看:
對於FishWebLib DEMO來說,它使用了 cs, ascx 這樣的副檔名,
而且這二個副檔名按照預設的配置是禁止訪問的,所以在那個樣本中,這段配置的用途是將這二個副檔名變成允許訪問。
我在使用Windows7的IIS7.5時,還發現一個與IIS6不同的地方,它會預設為每個網站建立一個獨立的應用程式集區,而且運行帳號也不是NETWORK SERVICE,
不過,我們可以容易地在【應用程式集區】的屬性中去修改它。
小結:
在IIS7.5中部署ASP.NET網站是件容易的事,前提是:事先準備好web.config中的system.webServer配置節。
然後只需要建立在IIS中建立一個網站,並指向程式目錄即可。
注意:如果程式需要訪問本地檔案或者資料庫,那麼還需要設定檔案系統或者資料庫的存取權限,具體可參考前面相關小節。
80連接埠和網域名稱
在前面的示範中,為了簡單,選擇了25678這個連接埠,那是因為80連接埠已被使用。
這樣做實際上不影響網站的運行,不過,URL看起來就不美觀了。
通常HTTP預設是使用80連接埠,如果使用這個連接埠,那麼URL中就不會出現連接埠號碼了。
為了讓URL地址看起來更美觀,按下來我將示範如何使用80連接埠。
在IIS中,為了能讓一個網站程式運行在80號連接埠中,有2個辦法:
1. 為網站程式使用其它的IP地址的80連接埠。
2. 為網站指定網域名稱綁定。
我們可以在網卡的配置中新增一個IP地址(如果已經有多個IP就不用這樣做了):
然後在IIS中,為網站設定【綁定】,使用這個IP地址了。請參考:
除了使用新IP地址的方式外,我們還可以使用網域名稱的方式讓網站可以在80連接埠下面運行。
方法還是在IIS中設定網站的【綁定】操作,給網站指定一個網域名稱即可:
最終的設定應該是下面這個樣子的:
此時我們就可以使用下面二種方式來訪問我的樣本網站了:
http://192.168.0.222
http://www.mymvc-demo.com
不過這裡又有個新問題:網域名稱從哪裡來?
答案有二個(對於示範來說):
1. 修改 C:\Windows\System32\drivers\etc\hosts 檔案,
增加一個映射條目:127.0.0.1 www.mymvc-demo.com 即可。
2. 如果您使用的是Windows Server的作業系統,也可以自己給自己分配網域名稱,請繼續閱讀。
在Windows Server的作業系統中,我們可以使用DNS服務建立自己的網域名稱,大致的過程是:
1. 建立一個反向尋找地區。
2. 建立一個正向尋找地區。
3. 在正向尋找地區建立一個WWW的主機。
4. 在IIS中為網站設定綁定,指向新的網域名稱。
5. 設定網卡的DNS伺服器位址,指向有DNS服務的機器。
這種方式或許對於單台機器來說,比直接修改host檔案要麻煩,但如果是在區域網路內部使用將會非常方便。
DNS配置的相關過程如下:(嚮導中沒有貼圖的步驟可以直接確定)
現在我們就可以使用網域名稱的方式來瀏覽我的樣本了:
如果,您認為閱讀這篇部落格讓您有些收穫,不妨點擊一下右下角的【推薦】按鈕。
如果,您希望更容易地發現我的新部落格,不妨點擊一下右下角的【關注 Fish Li】。
因為,我的寫作熱情也離不開您的肯定支援。
感謝您的閱讀,如果您對我的部落格所講述的內容有興趣,請繼續關注我的後續部落格,我是Fish Li 。