1. 有關于URL的重寫,本文也隻是拿來主意。相繼有MS的元件“ URLRewriter”和在Global.asax裡的“ Application_BeginRequest()”編碼方式,以及IIS裡的ISAPI設定。 娜列下來,實作方法也都很簡單。 方法一:MS元件 這裡也不用詳解了,相關請看: http://www.microsoft.com/china/msdn/library/webservices/asp.net/URLRewriting.mspx 用法很簡單,隻需要把元件URLRewriter.dll拷到應用程式的bin目錄下,然後在web.config下加入如下代碼: 在 < configuration ></ configuration > 中加入: <configSections> <sectionname="RewriterConfig"type="URLRewriter.Config.RewriterConfigSerializerSectionHandler, URLRewriter"/> </configSections> <RewriterConfig> <Rules> <RewriterRule> <LookFor>~/(/d{4})/(/d{2})/Default/.aspx</LookFor> <SendTo>~/Default.aspx?ID=$1</SendTo> </RewriterRule> </Rules> </RewriterConfig> 然後在<system.web></system.web>中加入: < httpHandlers > <addverb="*"path="*.aspx" type ="URLRewriter.RewriterFactoryHandler, URLRewriter" /> </ httpHandlers > 最後在位址欄上鍵入:http://localhost/Test/2004/12/News.aspx 效果出來了。 上面的<LookFor>~/(/d{4})/(/d{2})/News/.aspx</LookFor>這句這正規表達式URL,即被重寫的URL,而<SendTo>~/Default.aspx?ID=$1</SendTo>這一句為原始URL位址。其中的$1為第一個正規表達式值(上面例子為:2004),以此類推,第二個即為$2 方法二: Application_BeginRequest() 在應用程式中建立一個XML檔案,檔案内容為:檔案名ReWriter.config <? xml version ="1.0" encoding ="utf-8" ?> < ReWriterUrls > <rule> <old>(.*)/News/(/d{4})/Default/.aspx</old> <new>../../Default.aspx?id=$2&type=$3</new> </rule> </ ReWriterUrls > 在Global.asax檔案中的 Application_BeginRequest(Object sender, EventArgs e)加入代碼: try { string path=Server.MapPath("~/ReWriter.config"); XPathDocument myXPathDocument = new XPathDocument(path); XPathNavigator myXPathNavigator = myXPathDocument.CreateNavigator(); XPathNodeIterator myXPathNodeIterator = myXPathNavigator.Select ("//rule"); System.Text.RegularExpressions.Regex oReg; string ReWriteUrl; while (myXPathNodeIterator.MoveNext()) { //oReg=new Regex(oNode.SelectSingleNode("url/text()").Value); XPathNavigator nav2 = myXPathNodeIterator.Current.Clone(); string oldString="",newString=""; XPathNodeIterator it2 = nav2.Select("old"); while(it2.MoveNext()) { oldString = it2.Current.Value; break; } it2 = nav2.Select("new"); while(it2.MoveNext()) { newString = it2.Current.Value; break; } if(oldString != "" && newString != "") { oReg = new System.Text.RegularExpressions.Regex(oldString); if(oReg.IsMatch(Request.Url.ToString())) { ReWriteUrl = oReg.Replace(Request.Url.ToString(),newString); HttpContext.Current.RewritePath(ReWriteUrl); break; } } } } catch { } 最後在位址欄上鍵入:http://localhost/Test/News/2004/Default.aspx 效果出來了。 2 Asp.net 用url重寫(URLReWriter)實作任意二級域名 好久沒有寫技術文章,如果大家看不明白,就多看幾篇,汗,或者,在文章的後面回複(這是最有效的辦法),我會盡力幫助大家解答疑惑. 來找這篇文章的,應該都知道什麼叫二級域名吧,廢話就不說了.但是讨論前,先要明白一個思想問題. 很多朋友一直考慮不清(我前幾天也一直搞不明白)的問題是,我鍵入一個位址後,怎麼這個url就被重寫了? 第一步:在浏覽器鍵入了一個位址,比如http://love.kerry.com,點回車後,都發生了什麼? 為了把問題簡單化,我來這樣解釋: 第二步:首先,鍵入的位址被解析,最終來到了一台web伺服器.交給IIS處理.在.net的世界中,IIS會把這樣的請求再交給一個web處理器 處理,最後,該 web處理器 把處理的結果傳回給浏覽器,顯示給使用者看. 請不用忽略這樣一個問題,第二步的所有事情都是在伺服器端做的.在這些事情進行的時候,使用者端的浏覽器上面的位址不會改變.即使最後 web處理器 把處理結果傳回來的時候,上面的位址也不會改變. 一開始鍵入的url,隻是起一個敲門的作用,門敲完了,作用就算結束了,隻有你的眼睛可以看到那個位址,浏覽器,伺服器等都不知道這個位址. 然後要明白的問題是,所謂url重寫,也隻是web開發人員知道的内幕情況,使用者根本不知道發生了什麼,他認為自己鍵入的位址就是應該出來螢幕上顯示的結果.也就是說,我們在幕後控制要顯示的内容. 接下來要考慮的是,怎麼樣控制顯示的内容? 從上面說的過程,很明顯要在 web處理器 的工作這一步動手腳. 一個最簡單的考慮是,使用者敲入了一個簡單的不帶任何參數位址, http://love.kerry.com然後我們把這個位址改成一個符合程式需要的帶參數的位址, http://kerry.com?lover=notus,最後處理之. 所謂的url重寫,就是在這一步. 用.net的術語來說,我們需要給應用程式注冊一個httpmodule,用來處理特定的url 注冊httpmodule,在web.config, 處理url,在我們提供的httpmodule程式中 大體相當于這樣的一段程式 //用我們的httpmodule程式截獲原始url String OriginalUrl=” http://love.kerry.com”; //處理原始url,得到最後需要的url,值為http://kerry.com?lover=notus String FinalUrl=Rewrite(OriginalUrl); // context重新将url在内部發送給IIS處理 context.RewritePath(FinalUrl); 接下來,我們來實作url重寫. 第一步:确定要對哪些url執行重寫,即制定重寫規則 第二步:編寫httpmodule處理程式 第三步:将編寫的httpmodule整合入web程式,開始工作. 上面就是url重寫的基本知識,而用url重寫實作二級域名,過程一樣.因為無論是二級域名還是三級域名,都是一個url位址.隻要我們截獲這個url位址,就可以在處理的時候動手腳. 這些工作挺麻煩,但是網絡上已經有高人給我們寫了這樣的程式,參看下面的文章: http://www.microsoft.com/china/msdn/library/webservices/asp.net/URLRewriting.mspx http://www.cnblogs.com/jzywh/archive/2005/09/29/246650.html http://www.cnblogs.com/jzywh/archive/2006/02/20/334004.html 文章結束了. 在實施過程中會碰到一些問題,大多是因為看上面的文章不仔細産生的,但是說實話,那麼長的文章要看完也不容易.下面我來記錄一些重要的問題.其中最後的兩個問題,用具體的代碼展示了如何處理重寫的目标url以達到我們的要求 為什麼非要用泛解析? 看了好多朋友的回複,我想現在可能有這樣的誤解,即,這篇關于url重寫的文章隻是給大家介紹一些處理方法.至于泛解析不泛解析,并不重要. 如果你不需要實作任意二級域名,那就用不着去實作泛解析,直接把你需要的二級域名定死,然後在url重寫裡處理好了! 再退一步,如果連二級域名都不用實作,僅僅是對一個固定域名下的url進行重寫,那都不需要修改msdn的那個urlrewriter,直接拿來用就可以實作了簡單的url重寫. zyw對這個項目進行的修改,隻是為了取到全部的url進行更大限度的控制.而如我們所見,一開始msdn的那個urlrewriter并不關心域名的問題 我一開始給文章起這樣的題目,是因為最近我項目裡用到了,寫文檔的時候順便就把這個文章寫了 微軟的URLRewriter是什麼?這個項目在哪裡下載下傳的? 這個是在msdn上一篇介紹URLRewriter的文章中提供的示例程式,可以在這裡下載下傳到 http://www.microsoft.com/china/msdn/library/webservices/asp.net/URLRewriting.mspx 怎麼使用這些代碼?麻煩嗎? 肯定的說,不麻煩,要做的事情有: 下載下傳代碼到你的機器上. 安裝後,把URLRewriter這個項目添加到你自己的工程中 按照上面給的位址裡的方法,修改代碼 配置web.config,開始使用. 什麼是httpmodule? 簡單了解,就是一塊處理http請求的程式 更詳細的了解,請查閱sdk文檔. 怎麼樣實作泛解析? 首先,在域名服務商那裡添加一個*.kerry.com的二級域名,指向你的伺服器ip 然後,在IIS裡建立一個站點,這個站點的主機頭留白,一般端口是80. 這個站點就是整個伺服器端口80的預設網站. 給這個站點添加一個通配符應用程式映射(IIS站點屬性 ->主目錄 -> 配置),這個映射的目的是要asp.net ISAPI接管任何沒有在IIS裡明确的二級域名站點. 随便輸入二級域名的時候,發生了什麼? 當IIS檢測到傳入的url是一個二級域名的時候,它會先檢查IIS上有沒有注冊了這個二級域名的站點,如果有,就轉入到這個站點,否則,就會轉到預設站點,這個預設站點就是之前配置的主機頭為空的那個站點.是以,一個端口隻能有一個主機頭為空的站點. 我們已經設定由asp.net ISAPI接管這些沒有家的孩子.寫程式,分析傳入的url,執行重寫. 為什麼我的httpmodule好像沒有起作用? 在httpmodule程式裡設定斷點後,無論怎麼樣,流程都沒有從這裡走.原因在于,你沒有向web程式注冊你的httpmodule程式.這個工作需要在web.config中完成. <system.web> <httpModules> <add type="URLRewriter.ModuleRewriter, URLRewriter" name="ModuleRewriter" /> </httpModules> </system.web> 為什麼總是提示我”未知的配置節RewriterConfig錯誤” 這是因為你沒有向web程式注冊你的RewriterConfig配置節. 這個工作需要在web.config中完成. <configSections> <section name="RewriterConfig" type="URLRewriter.Config.RewriterConfigSerializerSectionHandler, URLRewriter" /> </configSections> 然後,你可以在<configuration>裡使用RewriterConfig節配置規則了. url是在httpmodule的哪個部分處理的? 大多的工作是在URLRewriter. ModuleRewriter. Rewrite()方法裡.關鍵階段是這裡: if (re.IsMatch(requestedPath)) 很明顯,這個判斷傳入的url是否是我們要重寫的url,大家接着看, String sendToUrl = RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, re.Replace(requestedPath, rules[i].SendTo)); 這裡接受到web.config中配置的要轉到的目标url RewriterUtils.RewriteUrl(app.Context, sendToUrl); 在内部把url重寫. 我不想把二級域名寫死在web.config中,而且我要重寫的目标url也不能寫死.比如我們有這樣的需要 Love.kerry.com實際的處理頁面是kerry.com/action.aspx?id=1 call.kerryl.com實際的處理頁面是kerry.com/action.aspx?id=2 walkwith.kerry.com實際的處理頁面是kerry.com/walk.aspx 要怎麼處理? 這個時候,就需要在上面說的那幾個代碼裡做手腳. if (re.IsMatch(requestedPath)) { //找到url裡的二級域名 string [] UserHost = app.Request.Url.Host.Split ( new Char [] { '.' } ); string domain2=UserHost [0]; //根據需要設定要重寫的目标url string sendToUrl ; if(domain2==” Love”) sendToUrl =” /action.aspx?id=1”; else if(domain2==” call”) sendToUrl =” /action.aspx?id=2”; else i f(domain2==” walkwith”) sendToUrl =” /walk.aspx”; RewriterUtils.RewriteUrl(app.Context, sendToUrl); } 在web.config裡配置規則的時候,需要這樣 <RewriterRule> <LookFor>http://(/w+)/.kerry/.com</LookFor> <SendTo>/test.aspx</SendTo> </RewriterRule> (/w+)用來比對任意字元串 這裡的test.aspx随便寫别的也可以,因為我們根本沒有用它. 我有好多不确定二級域名的站點,但是每個站點的頁面确定,每個二級域名站點的内容實際上根劇不同的id從資料庫調, 情況如這樣 http://localhost/kerry/action.aspx?id=1 love.kerry.com/walk.aspx http://localhost/kerry/action.aspx?id=14 like.kerry.com/walk.aspx 現在傳上去,不能顯示id參數,都改成二級域名的方式. 這個時候該怎麼辦? 首先配置規則 <RewriterRule> <LookFor>http://(/w+)/.kerry /.com/ walk.aspx</LookFor> <SendTo>/action.aspx</SendTo> </RewriterRule> 然後在程式裡這樣處理 //擷取二級域名 string [] UserHost = app.Request.Url.Host.Split ( new Char [] { '.' } ); string domain2=UserHost [0]; 根據域名獲得不同的編号 int id=getIDfromDomain(domain2); //獲得要轉向的基本url string sendToUrl = RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, re.Replace(requestedPath, rules[i].SendTo)); //加上id參數 if(id>0) sendToUrl=string.Format ( "{0}?id={1}" , sendToUrl , id ); else sendToUrl=”error.aspx”; //重寫 RewriterUtils.RewriteUrl(app.Context, sendToUrl); 如何比對目錄?寫了一個lookfor規則 http://love.kerry.com/,但是在浏覽器輸入這個位址, 總是不能正确的重寫,經過trace後發現根本不能比對,為什麼? 首先,我們應該知道,浏覽器實際上接受的不是http://love.kerry.com/,而是http://love.kerry.com/default.aspx ,是以,你的</LookFor>規則應該這樣寫 <LookFor> http://love.kerry.com/default.aspx </LookFor> 這個default.aspx應該是你在iis裡配置的預設文檔,如果你的是index.aspx或其他奇怪的名字,就寫成你自己的名字 同樣, http://love.kerry.com/fun 這個位址要比對,需要這樣的規則http://love.kerry.com/fun/default.aspx 但是,再羅嗦一句,你的檔案根本不需要有fun這個目錄,因為...重寫了嘛 我搜到網上還有另外一種解決辦法… 或許你是指這篇文章 http://blog.csdn.net/mengyao/archive/2007/01/25/1493537.aspx 大家可以看到,其基本的方法都是一樣的.之是以沒有把這個列在最前面,是因為這個做法有些取巧,可能一開始不是那麼好了解.但是我相信看到最後的朋友再看這篇文章,應該都會會心的一笑 Happy programming |