ASP.NET 提供了一個讓使用者輕鬆自訂客製化頁面的功能 - Web Parts
但是預設必須使用SQLExpress 或 SQL Server資料庫來儲存使用者的設定檔
對於不想大費周張開欄位使用資料庫儲存的人來說實在是很麻煩...
如果能夠使用一般的XML檔案來儲存使用者個人化資訊或許會是更方便的選擇。
稍微搜尋看了一些文章發現,其實 Web Part 是依賴.Net的 Personalization 個人化機制來儲存資訊
所以只要自己實做一個 PersonalizationProvider,想要把資訊存成任何格式都可以。
關於 Web Parts 的架構可以參考 聖殿祭司的文章 裡面說的很詳細
本篇文章的範例會將使用者的個人化資訊序列化之後,存在XML檔案中。
在微軟的 OpenSource 網站 CodePlex 中,找到了一個名為 ASP.NET XmlProvider Library 的 Project
剛好符合我想要用XML來儲存的需求,於是我引用了此Project中的 XmlProviders.dll 與 XmlProviders.XmlSerializers.dll
並且繼承改寫 XmlProviders.XmlPersonalizationProvider 來達成我的需求。
本文章因為只使用到 XmlPersonalizationProvider 的功能,ASP.NET XmlProvider Library 中的其他功能便不多加解釋,
有興趣請自行參考 ASP.NET XmlProvider Library 的 Source Code。
本文章範例將使用小弟比較熟的VB語法,看不習慣的人請自行 轉換
首先開啟 ASP.NET XmlProvider Library Project
從 ASP.NET XmlProvider Library 的 web.config 設定中我們可以看出,XmlPersonalizationProvider 會將瀏覽網頁的個人化資訊存到網站的 App_Data 目錄底下的 MyApp_Personalization.xml 中。

02

03

04

05

06

07

08

09

10

11
大家有沒有發現一個奇怪的地方... 如此一來,不管網站中有多少個使用者在瀏覽和編排 Web Parts 版面,全部都會儲存到同樣一份Xml檔案。
不就失去 Web Parts 個人化的意義了嗎?
於是我們直接檢視 XmlPersonalizationProvider 的 SourceCode,
發現可以直接複寫其中的 LoadPersonalizationBlobs. ResetPersonalizationBlob. SavePersonalizationBlob 方法,以及
並且新增 UserID 以及 StoreFilePath 屬性,就可以讓 XmlPersonalizationProvider 在讀取.儲存.和重載個人化檔案時,
都可以直接使用每個特定UserID資料夾中的Xml檔。

02

03

04 Private FUserID As String
05

06

07 ''' <summary>
08

09

10


11

12

13

14

15

16

17

18

19 ''' <summary>
20

21

22


23

24

25

26 If HttpContext.Current IsNot Nothing Then
27

28

29

30

31

32

33

34

35

36

37

38

39
40


41

42

43

44 Dim spaces As WorkspaceCollection = WorkspaceCollection.Load(StoreFilePath)
45

46

47

48

49 Dim space As Workspace = spaces.FindByUserAndPath(userName, path)
50

51

52

53

54

55
56


57

58

59

60 Dim spaces As WorkspaceCollection = WorkspaceCollection.Load(StoreFilePath)
61

62

63 If space IsNot Nothing Then
64

65

66

67

68

69
70


71

72

73

74 Dim spaces As WorkspaceCollection = WorkspaceCollection.Load(StoreFilePath)
75

76 If Not [String].IsNullOrEmpty(userName) Then
77

78

79 If space Is Nothing Then
80

81

82

83

84

85

86 space.PersonalizationBlob = dataBlob
87

88

89

90

91 spaces.Save(StoreFilePath)
92

93

另外為了讓頁面可以更方便的直接設定 UserID,我們可以將.Net 原本的 WebPartManager 控制項繼承下來,並且只簡單的加了一個 UserID 屬性。


02

03

04 Namespace WebControls
05

06 Public Class TWebPartManager
07

08

09 Private FUserID As String
10

11 ''' <summary>
12

13

14


15

16

17

18

19

20

21

22

23 End Class
24

25 End Namespace
最後只要在放置 Web Parts 頁面事件中,將當下登入的使用者ID,設定給繼承下來的 TWebPartManager 控制項,即可正常運行。


2

3

不知道各位有沒有發現到 TWebPartManager 控制項 所繼承的是 Microsoft.Web.Preview.UI.Controls.WebParts.WebPartManager
而不是原本的 System.Web.UI.WebControls.WebParts.WebPartManager,為什麼會有 NameSpace 上的差異呢?
主要是因為 Web Parts 控制項在原本.Net 2.0的版本下對於 FireFox 瀏覽器的支援性有問題,無法進行拖曳變換排版的功能。
所以我安裝了 ASP.NET 2.0 AJAX Futures January CTP,並且直接引用了修正的dll檔,所以會有命名空間上的差異。
ASP.NET 2.0 AJAX Futures January CTP 可 在此下載
請注意! 要使用新版本的 WebPartManager 必須搭配新版的 WebPartZone 才可使用,
因此我也繼承新版的 WebPartZone Control,名為 TWebPartZone,此 Control 不需要改寫任何方法。


02

03

04 Namespace WebControls
05

06 Public Class TWebPartZone
07

08

09 End Class
10

11 End Namespace
本範例提供了簡單使用 Web Parts 的一個基本範例,小弟功力還很弱。
僅與大家分享一些學習心得,請大家多多批評指教,謝謝!