使用apache時可以方便的使用mod_rewrite,來做重寫網址的功能,而到了IIS則可使用IIS URL Rewrite Module來達成,而.NET 3.5 SP1之後新增加了System.Web.Routing的組件,他可以做到和IIS URL Rewrite Module類似的事情,但是在背後運作的機制和使用上有不同之處,在本篇就不多做介紹。

本篇將說明如何使用Routing組件來達成URL重寫的功能,例如Blog.aspx?User=emn178的網址,以emn178/Blog的樣式呈現,此篇文章以實作IRouteHandler方式處理。

開發模式

要在開發時套用此功能,依照以下步驟設定

1. 專案[加入參考]=>[.NET]=>[System.Web.Routing]組件

2. VS2008不會自動將模組加入Web.config,所以需要額外加入以下內容,請找到相對應的位置加入

<configuration>
	<system.web>
		<compilation debug="true">
			<assemblies>
        			<add assembly="System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
			</assemblies>
		</compilation>
		<httpModules>
      			<add name="RoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
		</httpModules>
	</system.web>
	<system.webServer>
		<modules>
      			<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
		</modules>
		<handlers>
      			<add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
		</handlers>
	</system.webServer>
</configuration>

3. 實作Handler,例如建立BlogRouteHandler

public class BlogRouteHandler : IRouteHandler
{
    private string virtualPath;

    public BlogRouteHandler(string virtualPath)
    {
        this.virtualPath = virtualPath;
    }

    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        string origQueryStr = HttpContext.Current.Request.QueryString.ToString();
        string queryStr = "?User=" + requestContext.RouteData.Values["User"];

        if (!string.IsNullOrEmpty(origQueryStr))
            queryStr += "&" + origQueryStr;
        HttpContext.Current.RewritePath(string.Concat(virtualPath, queryStr));

        return BuildManager.CreateInstanceFromVirtualPath(virtualPath, typeof(Page)) as Page;
    }
}

4. 如果沒有Global.asax則[新增項目]=>[全域應用程式類別]

5. 於Global.asax中加入Routing註冊函式

void Application_Start(object sender, EventArgs e)
{
    // 應用程式啟動時執行的程式碼
    RegisterRoutes(RouteTable.Routes);
}

public static void RegisterRoutes(RouteCollection routes)
{
    routes.Add(new Route("{User}/blog", new BlogRouteHandler("~/Blog.aspx")));
}

說明:

由以上範例可發現,new Route("{User}/blog"表示你的規則,大括弧表示會變動的部分,變動的部分會傳入GetHttpHandler中的requestContext.RouteData

自訂更多的規則

假設現在要新增Blog.aspx?User=emn178&ArticleID=123變成emn178/Blog/123/的規則,而原來的規則也同時存在,將RegisterRoutes修改為

public static void RegisterRoutes(RouteCollection routes)
{
    routes.Add(new Route("{User}/blog", new BlogRouteHandler("~/Blog.aspx")));
    routes.Add(new Route("{User}/blog/{ArticleID}", new BlogRouteHandler("~/Blog.aspx")));
}

BlogRouteHandler修改為

public class BlogRouteHandler : IRouteHandler
{
    private string virtualPath;

    public BlogRouteHandler(string virtualPath)
    {
        this.virtualPath = virtualPath;
    }

    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        string origQueryStr = HttpContext.Current.Request.QueryString.ToString();
        string queryStr = "?User=" + requestContext.RouteData.Values["User"];
        if (requestContext.RouteData.Values["ArticleID"] != null)
            queryStr += "?ArticleID=" + requestContext.RouteData.Values["ArticleID"];

        if (!string.IsNullOrEmpty(origQueryStr))
            queryStr += "&" + origQueryStr;
        HttpContext.Current.RewritePath(string.Concat(virtualPath, queryStr));

        return BuildManager.CreateInstanceFromVirtualPath(virtualPath, typeof(Page)) as Page;
    }
}

套用到IIS6

Routing的規則在IIS6下會變成目錄不存在而無法顯示網頁,可以用以下的方式讓他交由ASP.NET去處理

1. 進入IIS管理頁面,在你的網頁應用程式按右鍵=>[內容]

2. 於目錄的頁籤下點擊[設定]

 01.png      

3. 接著點擊[新增]來新增對應

4. 執行檔選擇.NET Framework的aspnet_isapi.dll,例如:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll

5. 副檔名輸入 .*

6. 指令動詞選擇[限制於]並輸入GET,HEAD,POST,DEBUG

7. 不勾選[檢查檔案是否存在]

 02.png  

套用到IIS7

IIS7則不需額外設定就可使用

文章標籤
創作者介紹

小殘的程式光廊

emn178 發表在 痞客邦 PIXNET 留言(0) 人氣()