IHttpModule實現URL重寫

一、用自定義IHttpModule實現URL重寫

通常來講,要顯示一些動態數據老是採用帶參數的方式,好比製做一個UserInfo.aspx的動態頁面用於顯示系統的UserInfo這個用戶信息表的數據,那麼須要在其後帶上一個參數來指定要顯示的用戶信息,好比UserInfo.aspx?UserId=1用於顯示錶中編號爲1的用戶的信息,若是爲2則顯示錶中編號爲2的用戶信息。在一些系統中咱們可能看到的不是這樣的效果,可能會看到形如UserInfo2.aspx這樣的形式(固然形式能夠多樣,只要有規律就行),當點擊這樣一個連接時看到的效果和UserInfo.aspx?UserId=2的效果同樣,這裏就用到了URL地址重寫的目的。html

 

在實例化HttpApplication類時會根據web.config中的配置(包括系統級和當前網站或虛擬目錄級)實例化全部實現IHttpModule接口的集合,而後會將HttpApplication類的實例做爲參數依次調用每一個實現了IHttpModule接口的類的實例的Init()方法,在Init方法中能夠添加對請求的特殊處理。在HttpApplication中有不少事件,其中第一個事件就是BeginRequest事件,在這個事件中咱們能夠對用戶請求的URL進行判斷,若是知足某種要求,能夠按另一種方式來進行處理。web


  好比,當接收到的用戶請求的URL是UserInfo(\\d+).aspx這種形式時(這裏採用了正則表達式,表示的是UserInfo(數字).asp這種URL)咱們將會運行UserInfo.aspx?UserId=(\\d+)這樣一個URL,這樣網頁就能正常顯示了。正則表達式


  固然實現URL地址重寫還須要藉助一個類:HttpContext。HttpContext類中定義了RewritePath 方法,這個方法有四種重載形式,分別是:
  RewritePath(String)  使用給定路徑重寫 URL。
  RewritePath(String, Boolean)  使用給定路徑和一個布爾值重寫 URL,該布爾值用於指定是否修改服務器資源的虛擬路徑。
  RewritePath(String, String, String)  使用給定路徑、路徑信息和一個布爾值重寫 URL,該布爾值用於指定是否修改服務器資源的虛擬路徑。
  RewritePath(String, String, String, Boolean)  使用給定虛擬路徑、路徑信息、查詢字符串信息和一個布爾值重寫 URL,該布爾值用於指定是否將客戶端文件路徑設置爲重寫路徑。 瀏覽器


  對於這裏四個重載方法的區別我不一一詳細描述,由於在這裏只用帶一個參數的重載方法就能知足本文提出的要求。
咱們的步驟以下:
首先編寫自定義IHttpModule實現,這個定義只定義了兩個方法Dispose()和Init()。在這裏咱們能夠不用關注Dispose()這個方法,這個方法是用來實現如何最終完成資源的釋放的。在Init方法中有一個HttpApplication參數,能夠在方法中能夠自定義對HttpApplication的事件處理方法。好比這裏咱們的代碼以下: 服務器

        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(BeginRequest);
        }
 
        public void BeginRequest(object sender, EventArgs e)
        {
            HttpApplication application = sender as HttpApplication;
            HttpContext context = application.Context;
            HttpResponse response = context.Response;
 
            //重寫後的URL地址 
            string path = context.Request.Path;
            string file = System.IO.Path.GetFileName(path);
            Regex regex = new Regex("UserInfo(\\d+).aspx", RegexOptions.Compiled);
            Match match = regex.Match(file);
 
            if (match.Success)
            {
                string userId = match.Groups[1].Value;
                //將其按照UserInfo.aspx?UserId=123這樣的形式重寫,確保能正常執行  
                string rewritePath = "UserInfo.aspx?UserId=" + userId;
                context.RewritePath(rewritePath);
            }
        }

 

注意在上面的代碼中採用了正則表達式來進行匹配,使用正則表達式的好處就是在處理格式化文本時至關靈活。除此以外,咱們在處理方法中僅僅對知足要求的URL進行重寫,對於不知足要求的URL則無需進行重寫,因此這樣就不會干擾沒有重寫的URL的正常運行(好比Index.aspx)。app


從那段從《ASP.NET夜話》摘出的話中能夠看出,僅僅是編寫本身的IHttpModule實現仍是不夠的,咱們還須要讓處理Web請求的程序直到咱們編寫的IHttpModule實現的存在,這就須要在web.config中配置。在本實例中只須要在本ASP.NET項目中的web.config節點中增長一個<httpModules></httpModules>節點(若是已存在此節點則能夠不用添加),而後在此節點中增長一個配置便可,對於本實例,這個節點最終內容以下:asp.net

    <httpModules>
      <add name="MyHttpModule" type="WebApplication1.MyHttpModule,WebApplication1"/>
    </httpModules>

 

UserInfo.aspx.csoop

            if (!Page.IsPostBack)
            {
                string queryString = Request.QueryString["UserId"];
                int userId = 0;
                if (int.TryParse(queryString, out userId))
                {
                    Response.Write(userId.ToString());
                }
                else
                {
                    Response.Write("error");
                }
            }

 

效果圖
2010-03-17_092034 2010-03-17_092043 網站

 

以上內容轉自:http://blog.csdn.net/zhoufoxcn/archive/2009/07/14/4346356.aspx spa

 

二、使用URLRewriter

 

web.config的配置

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="RewriterConfig" type="URLRewriter.Config.RewriterConfigSerializerSectionHandler, URLRewriter" />
  </configSections>
  <RewriterConfig>
    <Rules>
      <RewriterRule>
        <LookFor>~/news/(.[0-9]*)\.html</LookFor>
        <SendTo>~/news/new.aspx?id=$1</SendTo>
      </RewriterRule>
      <RewriterRule>
        <LookFor>~/web/index.html</LookFor>
        <SendTo>~/web/index.aspx</SendTo>
      </RewriterRule>
    </Rules>
  </RewriterConfig>
  <system.web>
    <httpHandlers>
      <add verb="*" path="*.aspx" type="URLRewriter.RewriterFactoryHandler, URLRewriter" />
      <add verb="*" path="*.html" type="URLRewriter.RewriterFactoryHandler, URLRewriter" />
    </httpHandlers>
    <compilation debug="true"/>
  </system.web>
</configuration>

 

這裏簡單介紹一下:

<RewriterConfig>
   <Rules>
   <RewriterRule>
      <LookFor>要查找的模式</LookFor>
      <SendTo>要用來替換模式的字符串</SendTo>
   </RewriterRule>
   <RewriterRule>
      <LookFor>要查找的模式</LookFor>
      <SendTo>要用來替換模式的字符串</SendTo>
   </RewriterRule>
   </Rules>
</RewriterConfig>

 

httpHandlers的設置主要是配合IIS將請求從新定義處理,這裏也比較關鍵,若是不存在合理的httpHandlers,那麼,訪問確定會失敗的。關於正則表達式,能夠到百度裏搜索:"經常使用正則表達式",會有不少。

 

News.aspx.cs

            if (!Page.IsPostBack)
            {
                // http://localhost:10445/News/1.html
                string queryString = Request.QueryString["Id"];
                int newsId = 0;
                if (int.TryParse(queryString, out newsId))
                {
                    Response.Write(newsId.ToString());
                }
                else
                {
                    Response.Write("error");
                }
            }

 

配置IIS解析.html文件
右鍵點個人電腦-->管理-->展開'服務和應用程序'-->internet信息服務-->找到你共享的目錄-->右鍵點擊屬性 -->點擊'配置'-->映射下面 -->找到.aspx的可執行文件路徑 複製路徑-->粘貼路徑-->擴展名爲".html"-->而後把檢查文件是否存在的勾去掉這樣就能夠了,若是遇到「肯定」按鈕失效,能夠用鍵盤事件編輯路徑便可解決。

效果圖
2010-03-17_092701 2010-03-17_092712

以上內容轉自:http://www.cnblogs.com/zhangyi85/archive/2008/04/20/1161826.html

注意

HttpModule默認處理aspx頁面沒有問題,可是若是在IIS上配置html也經過HttpModule處理時會出現死循環沒法跳出html頁面的問題,在web.config上加上

<add verb="*" path= "*.htm" type= "System.Web.StaticFileHandler"/></httpHandlers>

可解決。

 

三、修改UrlRewriter 實現泛二級域名

你們應該知道,微軟的URLRewrite可以對URL進行重寫,可是也只能對域名以後的部分進行重寫,而不能對域名進行重寫,如:可將 http://http://www.abc.com//1234/  重寫爲 http://www.abc.com/show.aspx?id=1234  但不能將
http://1234.abc.com/  重寫爲  http://www.abc.com/show.aspx?id=1234。

要實現這個功能,前提條件就是  http://www.abc.com/ 是泛解析的,再就是要修改一下URLRewriter了。
總共要修改2個文件

1.BaseModuleRewriter.cs

        protected virtual void BaseModuleRewriter_AuthorizeRequest(object sender, EventArgs e)
        {
            HttpApplication app = (HttpApplication)sender;
            //	Rewrite(app.Request.Path, app);
            Rewrite(app.Request.Url.AbsoluteUri, app);
        }

就是將  app.Request.Path 替換成了  app.Request.Url.AbsoluteUri

		// iterate through each rule...
			for(int i = 0; i < rules.Count; i++)
			{
				// get the pattern to look for, and Resolve the Url (convert ~ into the appropriate directory)
			   //	string lookFor = "^" + RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, rules[i].LookFor) + "$";
                string lookFor = "^" + rules[i].LookFor + "$"; 
 
				// Create a regex (note that IgnoreCase is set...)
				Regex re = new Regex(lookFor, RegexOptions.IgnoreCase);
 
				// See if a match is found
				if (re.IsMatch(requestedPath))
				{
					// match found - do any replacement needed
					string sendToUrl = RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, re.Replace(requestedPath, rules[i].SendTo));
 
					// log rewriting information to the Trace object
					app.Context.Trace.Write("ModuleRewriter", "Rewriting URL to " + sendToUrl);
 
					// Rewrite the URL
					RewriterUtils.RewriteUrl(app.Context, sendToUrl);
					break;		// exit the for loop
				}
			}


string lookFor = "^" + RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, rules[i].LookFor) + "$";
改爲了
string lookFor = "^" + rules[i].LookFor + "$";

 

web.config

      <RewriterRule>
        <LookFor>http://(\w+)\.lost\.com/</LookFor>
        <SendTo>/abc.aspx?name=$1</SendTo>
      </RewriterRule>

 

abc.aspx.cs

            if (!Page.IsPostBack)
            {
                Response.Write(Request.QueryString["name"]);
            }

 

效果圖


2010-03-17_100637 2010-03-17_101350

 

1.域名解析問題
      輸入了域名http://1234.abc.com/,瀏覽器提示找不到網頁。首先,你應該確認你的域名是否支持泛域名解析,就是讓全部的二級,三級域名都指向你的server。其次,要保證你的站點是服務器上的默認站點,就是80端口主機頭爲空的站點便可以直接用IP能夠訪問的http://1234.abc.com/,要麼要提示你的站點的錯誤信息,要麼會正確的執行你定義的URLRewrite,要麼顯示你的站點的首頁。

2.不能執行重寫的問題
      若是你確認你的域名解析是正確的,可是仍是不能重寫,訪問http://1234.abc.com/會提示路徑"/"找不到...,
若是是這樣的話,你先添加  ASPNET_ISAPI的通配符應用程序映射(這一步是必需的,Sorry!沒有在上篇文章中提出來)。
操做方法:IIS站點屬性 ->主目錄 ->  配置

 

 

3. 默認首頁失效,由於把請球直接交給asp.net處理,IIS定義的默認首頁將會失效,出現這種情形:
訪問http://www.abc.com/ 不能訪問首頁,而經過http://1234.abc.com/default.aspx能夠訪問。 爲解決這個問題,請本身在Web.Config中設置 lookfor /  to /default.aspx 或 index.aspx ..的重寫,徹底能夠解決問題。

相關文章
相關標籤/搜索