297
技術社區[雲棲]
詳談關於Discuz!NT 的URL地址重寫(URLRewrite)
在Discuz!NT中的前台頁麵訪問(特別是aspx)是被HttpModule接管的,所以大家在Discuz.Web
項目的目錄下看到的唯一"aspx文件"是index.aspx,而所有其它前台頁麵都有“/aspx/”文件夾下的相應
的子目錄中,而這些子目錄名稱是與後台所“生成”的模板存在對應關係的。而這種“關係”的綁定是通
過dnt_templates(模板數據表)來進行關聯的。而有關模板機製的文章詳見:
“Discuz!NT 模板機製分析”一文。
今天所要說的其實是模板機製的“延續”,當然這種“延續”僅是我個人的觀點。因為地址重寫最終
要綁定的路徑,恰恰與模板機製是有著前後唿應的關係。首先請大家看一下這張圖:
圖1 :[discuz!NT 的web.config文件相關配置節]
相信對於那些以前做過“URL重寫”的朋友看到這一行配置的第一反映可能就是要去Discuz.Forum
.HttpModule類中一看究竟。同時考慮到在<httpModules>配置節中加入處理的資料在網上有許多,所
以這裏就不再多費唇舌了。
另外如果大家感興趣味的話,也可以抽空看看我的這篇文章,"NET框架中的 Observer 模式"。雖
然該文是我在挖.net底層代碼時是寫的一些個人想法,可讀性不高,但我相信會對大家有所幫助的:)
好了,下麵讓我們看一下在Discuz.Forum項目中的HttpModule類中的一些信息,看看URL重寫到
底如何實現:)

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

上麵代碼中的Init(HttpApplication context)是HttpModule類進行操作的入口,所有實現
System.Web.IHttpModule 接口的類都必須實現這個函數。
同時大家看到的OnlineUsers.ResetOnlineList()方法主要是用於“重置(複位)在線表”,
而有關“在線用戶”的功能我會在以後專門寫文章來加以介紹,所以這裏大家隻要知道它要幹的
事(代碼如下)即可:)

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

而緊隨其後的事件綁定代碼就是一個關鍵點了,形如:


因為當通過瀏覽器提交請求時,IIS都會接管請求進行相應的操作(詳見DUDU的文章:" ASP.NET 2.0運行時
簡要分析")後,最終通過Web.config中的相應配置節(上圖所示)來執行用戶預定的處理操作。而我們的代碼就
在ReUrl_BeginRequest事件中(代碼如下,詳情見注釋):

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42



43

44

45

46

47



48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66



67

68

69

70

71

72

73



74

75

76

77

78

79

80

81



82

83

84

85

86

87



88

89

90

91

92

93

94

這樣就實現了偽URL的動態轉換(地址重寫)。而相應的“SiteUrls”類則是對偽URL設置信息
進行訪問讀取的“封裝類”,目的就是要將Discuz.Web項目中config文件夾下的urls.config文件轉換
成可訪問的信息對象。形如:

2

3

4

5

6

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

154

155

164

165

166

167

168

因為代碼很簡單,這裏就不再另行說明了。
到目前,我們知道了要通過“urls.config”文件來進行偽URL重寫,那麼這個文件中的數據到底是什麼
樣子呢,下麵就是在成功安裝discuz!nt 2.0產品之後的文件內容:



































大家看到了吧。就目前而言偽URL重寫的頁麵(page節點)包括如下幾個:
showforum.aspx(版塊列表),showtopic.aspx(主題列表),userinfo.aspx(用戶信息),rss.aspx,
雖然不多,但已基本滿足了設置需要。
而設置(配置)管理的頁麵在後台的“全局”-->“常規選項”-->“基本設置”-->“編輯偽靜態url替換
規則”,如果所示:
相信聊到這裏大家對我們產品的這項功能應該有個大概認識了,但這不並是全部的設置,因為如果要接管
形如"showforum-1-2.htm"這樣的頁麵,是必須要到IIS裏去“搞一把”的。因為默認的IIS中對htm(html)
的處理是無法實現將上麵的鏈接轉成“showforum.aspx?forumid=1&page=2”的形式的,所以這裏要參考
一下官方文檔(使用偽Url地址)中的方法,相應圖示如下:
好的,下麵再接著聊一下關於與第三方產品“整和”的問題。因為目前大多數采用 .net技術開發的主流產品
(如博客園等)都會或多或少使用與本文類似或相同的做法來實現地址重寫功能。比如:繼承並實現IHttpHandler
接口。
當然我們的產品所采用實現IHttpModule的方式會比IHttpHandler更早一步被 IIS進行處理。所以如果出現
了這種情況,我個人建議是改動我們產品中的代碼,通過在上述 ReUrl_BeginRequest事件中加入條件分支(第
三方程序的偽地址規則)來實現“地址重寫整合”;當然如果第三方的 (重寫)規則太複雜的話,也可以在我們產
品的相應代碼中加入條件分支(隻要出現第三方請求的鏈接頁麵或指定路徑時),但不作任何處理(直接綠燈放行
),這樣就會轉入到第三方的偽URL重寫規則代碼的“勢力範圍”內了。
當然如果第三方也使用類似IHttpModule的實現方式,則要看是誰的配置先出現在web.config中的相應配置
節中了。因為“先入為主”嘛,如果先後順序已明確的話,那麼先被加載的HttpModule 模塊就要做一下變動了,
以便不會幹擾後麵的HttpModule模塊的正常運行了。因為我手上這方麵的實例也不多,所以隻能在這裏聊聊我本
人的一些看法,相信隨著官方“整合案例” 的增加,這方麵的資料會得到更大的補充。
最後更新:2017-04-02 03:42:39