[ASP.net/IIS] 多個網站併成同一個WebSite專案開發、部署技巧
在進入正題前,先回顧一般情況下,如果有一個案子,須同時開發二個以上的網站
通常大概這樣做……(以下以WebSite專案當範例)
建立第一個WebSite,架構如下:
Comman.cs是所有WebSite都會用到的共同邏輯
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
public class Comman
{
public Comman()
{
}
public string getBanner()
{
return "廣告輪播 by AdRotator控制項";
}
}
images/demo.png是第一個網站自己擁有的圖片資源(相對路徑)
index.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="index.aspx.cs" Inherits="index" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>第一個網站的首頁</title>
</head>
<body>
<form id="form1" runat="server">
<img src="images/demo.png" alt="Shadow與愉快的程式" />
</form>
</body>
</html>
index.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Configuration;
public partial class index : System.Web.UI.Page
{
string Conn_E = WebConfigurationManager.ConnectionStrings["Conn_E"].ConnectionString;//資料庫連線字串
protected void Page_Load(object sender, EventArgs e)
{
Response.Write("Shadow1的網站,做Shadow1的事情..." + "<br/>");
Comman com = new Comman();
Response.Write(com.getBanner() + "<br />");
Response.Write("連線字串:" + this.Conn_E);
}
}
執行首頁結果:
再建立第二個WebSite:
Comman.cs是所有WebSite都會用到的共同邏輯
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
public class Comman
{
public Comman()
{
}
public string getBanner()
{
return "廣告輪播 by AdRotator控制項";
}
}
images/demo.png是第二個網站自己擁有的圖片資源(相對路徑)
index.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="index.aspx.cs" Inherits="index" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>第二個網站的首頁</title>
</head>
<body>
<form id="form1" runat="server">
<img src="images/demo.png" alt="Yahoo奇摩" />
</form>
</body>
</html>
index.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Configuration;
public partial class index : System.Web.UI.Page
{
string Conn_E = WebConfigurationManager.ConnectionStrings["Conn_E"].ConnectionString;//資料庫連線字串
protected void Page_Load(object sender, EventArgs e)
{
Response.Write("Shadow2的網站,做Shadow2的事情..." + "<br/>");
Comman com = new Comman();
Response.Write(com.getBanner() + "<br />");
Response.Write("連線字串:" + this.Conn_E);
}
}
執行首頁結果:
以上都是舉比較簡單的例子,如果WebSite有第三個、第四個……以此類推
這邊分享一下個人經驗,那時候我一個人維護4x個網站,架構都是這樣,一個WebSite有自己的Web.config,有自己的App_Code
但事實上那4x個網站的Web.config檔幾乎一模一樣,連線字串一樣,SMTP_SERVER設定一樣…
App_Code裡共同邏輯的類別檔也都一樣
有天客戶承辦人一聲下令,所有網站應該要像http://malsup.com/jquery/cycle/ ,廣告輪播Banner要能夠自己輪播,不要畫面重整一次才撈新的圖片
呃…( ̄▽ ̄|||),後來我先改其中一個WebSite的Comman.cs檔
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
public class Comman
{
public Comman()
{
}
public string getBanner()
{
return "廣告輪播 by jQuery";
}
}
然後改完的Comman.cs檔就Copy-Paste貼到其他4x個WebSite的App_Code底下覆蓋
因為是遠端連線到客戶那邊的機器作業,所以光是Copy-Paste就花了我一個上午的時間
而且這種需求常常發生,導致我在思考,是不是哪天應該把App_Code底下共同邏輯的CS檔改成WebService的方式?
但改成WebService的方式,其他index.aspx.cs的程式碼就一定也要跟著改呼叫方式,以4x個網站來說,真是浩大工程…
經過此次的教訓,後來開發的新專案
我整理出一種
各網站可以共用Web.config檔,也可以共用App_Code,各網站自己的圖片資源還是歸自己,正式上線時的DomainName對應仍對應各自自己的網站
以User角度來看會覺得是多個網站,以Developer角度來看其實只有一個WebSite專案
重點是會這麼做,一切都是為了維護方便
請看以下建立步驟:
先在檔案總管新增一個資料夾
Step 1. shadowAll
Step 2.把共用的檔案全複製到此資料夾裡(Web.config、App_Code)
Step 3. 把剛剛建立的兩個WebSite資料夾也搬到此資料夾內
Step 4.把那兩個WebSite裡重覆的檔案都刪除
Step 5.開Visual Studio先執行shadow1和shadow2內的index.aspx看看有沒有問題
shadow1的index.aspx執行結果:
shadow2的index.aspx執行結果:
看起來沒問題
至目前為止多個網站併成同一個WebSite專案到這邊告一段落,如果客戶的要求會更改到共同邏輯的話,這次只要改一遍
全部資料夾裡的程式大家都一起套用,就不用再Copy-Paste 40幾次了
再來是部署上線問題
各網站自己的圖片資源還是歸自己:由於各資料夾裡的圖片路徑都是採用相對路徑,所以此部份不用擔心
正式上線時的DomainName對應仍對應各自自己的網站:
部署環境Window 7 (IIS7.5)
shadow1資料夾對應DomainName:shadow1.no-ip.info
shadow2資料夾對應DomainName:shadow2.no-ip.info
Step 1.先在IIS裡,新增一個shadow1的站台
Step 2. 再新增一個shadow2的站台,請注意兩個站台的實體路徑指到同一個「shadowAll」資料夾(因為都在同一個WebSite專案)
接下來是重點!
為了達到「正式上線時的DomainName仍對應各自自己的網站」此條件
先確認shadow1和shadow2資料夾底下都有index.aspx後
Step 3. 在shadowAll網站根目錄下新增一個index.aspx程式
此index.aspx負責做導向動作,所以UI端不寫Code
index.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class index : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Request.Url.AbsoluteUri.Contains("shadow1.no-ip.info"))
{
Response.Redirect("shadow1/index.aspx");
}
else if (Request.Url.AbsoluteUri.Contains("shadow2.no-ip.info"))
{
Response.Redirect("shadow2/index.aspx");
}
else
{
Response.Redirect("shadow1/index.aspx");
}
}
}
Step 4. 回到IIS,確認shadow1和shadow2兩個站台的預設文件都是index.aspx且在最上面
Step 5. 測試&執行
在瀏覽器URL輸入http://shadow1.no-ip.info,執行結果:
在瀏覽器URL輸入http://shadow2.no-ip.info,結行結果:
執行起來沒問題,部署完成。
接著要測試幾種情況,看看這種開發方式經不經得起考驗
1.假設shadow1資料夾底下的index.aspx有兩個超連結,一個另開視窗連到http://www.google.com.tw
一個則是相對路徑連個另一資料夾的second.aspx程式
index.aspx
other/second.aspx.cs
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="second.aspx.cs" Inherits="shadow1_other_second" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<h1>你來到second.aspx了</h1>
</form>
</body>
</html>
在URL輸入:shadow1.no-ip.info
點選第一個超連結:
正常。
接著再點選第二個超連結:
也正常。所以超連結這部份測試OK
2.再假設一種情況,我見過有些人會把圖片的URL寫成<%= 網站URL %>資料夾/images/圖片.jpg
這裡就利用shadow1/index.aspx做示範,先看Web.config設定
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="shadow1Url" value="http://shadow1.no-ip.info/"/>
<add key="shadow2Url" value="http://shadow2.no-ip.info/"/>
</appSettings>
<connectionStrings>
<add name="Conn_E" connectionString=".\sqlexpress;Initial Catalog=NorthwindChinese;Integrated Security=True" />
</connectionStrings>
<system.web>
<compilation debug="false" targetFramework="4.0" />
</system.web>
<system.webServer>
<defaultDocument>
<files>
<add value="index.aspx" />
</files>
</defaultDocument>
</system.webServer>
</configuration>
然後shadow1/index.aspx.cs裡宣告
protected string shadow1Url = WebConfigurationManager.AppSettings["shadow1Url"];
protected string shadow2Url = WebConfigurationManager.AppSettings["shadow2Url"];
接著shadow1/index.aspx,兩個設定都讀讀看
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="index.aspx.cs" Inherits="index" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>第一個網站的首頁</title>
</head>
<body>
<form id="form1" runat="server">
<img src="<%= shadow1Url %>shadow1/images/demo.png" alt="Shadow與愉快的程式" />
<img src="<%= shadow2Url %>shadow1/images/demo.png" alt="Shadow與愉快的程式" />
</form>
</body>
</html>
執行結果:
兩張圖片都正常顯示出來(因為兩個DomainName都對應到同一個WebSite專案)
不過這邊個人建議shadow1資料夾裡的程式,為了避免造成維護上的困擾,請儘量使用shadow1對應的DomainName:shadow1.no-ip.info
以上不管怎麼測,跑起來功能都和 多個獨立WebSite專案相同,但在維護性方面,只有一個WebSite專案當然是比較好維護
而且到部署上線階段,客戶想把多個網站當做一個網站,只給一個DomainName
或客戶想要多個網站各自擁有自己的DomainName
用這種開發方式都足以應付,如此好用的技巧分享給大家^_^