下面是Portal消息處理的步驟:
1.客戶端發送請求
如果未登陸,則沒有Cookie,
如果是登陸頁面,則會生成Cookie並帶上.
如果已登陸,則已有Cookie,直接帶上.
2.服務端Global中對信息的處理
--1.在Global的Application_BeginRequest事件中將站點信息保存在HttpContext變量SiteSetting中,並根據請求的參數 TabIndex和TabId得到門戶配置信息並保存在HttpContext變量PortalSetting中;
//
每個請求都要建立PortalSettings並取得SiteSettings到HttpContext中,默認值設定TabIndex=0,TabId=1,
//
如果不是DesktopDefault頁面也要執行這個函數,這樣就是多余的了,不是嗎?
protected
void
Application_BeginRequest(Object sender, EventArgs e)
{
int
tabIndex
=
0
;
int
tabId
=
1
;
//
Get TabIndex from querystring
//
在當前請求字符中獲取tabIndex的值
if
(Request.Params[
"
tabindex
"
]
!=
null
)
{
tabIndex
=
Int32.Parse(Request.Params[
"
tabindex
"
]);
}
//
Get TabID from querystring
//
從當前請求字符中獲取tabId的值
if
(Request.Params[
"
tabid
"
]
!=
null
)
{
tabId
=
Int32.Parse(Request.Params[
"
tabid
"
]);
}
//
Build and add the PortalSettings object to the current Context
//
建立並添加PortalSettings(門戶站點設置對像)到HttpContext對像中
Context.Items.Add(
"
PortalSettings
"
,
new
PortalSettings(tabIndex, tabId));
//
Retrieve and add the SiteConfiguration DataSet to the current Context
//
將站點設置信息(數據集形式)添加到HttpContext中
HttpContext.Current.Items.Add(
"
SiteSettings
"
, Configuration.GetSiteSettings());
try
{
if
(Request.UserLanguages
!=
null
)
Thread.CurrentThread.CurrentCulture
=
CultureInfo.CreateSpecificCulture(Request.UserLanguages[
0
]);
else
//
Default to English if there are no user languages
Thread.CurrentThread.CurrentCulture
=
new
CultureInfo(
"
en-us
"
);
Thread.CurrentThread.CurrentUICulture
=
Thread.CurrentThread.CurrentCulture;
}
catch
{
Thread.CurrentThread.CurrentCulture
=
new
CultureInfo(
"
en-us
"
);
}
}
--2.在Application_AuthenticateRequest中根據cookie等信息驗證用戶身份並授與用戶角色;
//
對用戶身份進行驗證並授權
protected
void
Application_AuthenticateRequest(Object sender, EventArgs e)
{
if
(Request.IsAuthenticated
==
true
)
{
String[] roles;
//
不存入Cookie每次都從數據庫中讀取
UsersDB user
=
new
UsersDB();
roles
=
user.GetRoles(User.Identity.Name);
//
Create a string to persist the roles
//
以字符串的形式存儲用戶角色信息用";"分隔,一個用戶的多個角色
String roleStr
=
""
;
foreach
(String role
in
roles)
{
roleStr
+=
role;
roleStr
+=
"
;
"
;
}
//
Create a cookie authentication ticket.
//
創建身份角色驗證的憑據
FormsAuthenticationTicket ticket
=
new
FormsAuthenticationTicket(
1
,
//
version 版本
Context.User.Identity.Name,
//
user name cookie 名
DateTime.Now,
//
issue time 發布日期
DateTime.Now.AddHours(
1
),
//
expires every hour 過期日期
false
,
//
don't persist cookie 持久性(false)
roleStr
//
roles 用戶定義的數據初始化(";"分隔的角色字符串)
);
//
Add our own custom principal to the request containing the roles in the auth ticket
//
從 GenericIdentity 和角色名稱數組(GenericIdentity 表示的用戶屬於該數組)初始化 GenericPrincipal 類的新實例。
Context.User
=
new
GenericPrincipal(Context.User.Identity, roles);
}
}
3.在頁面中導入相應的頁面內容
--1.如果是DesktopDefault.aspx頁面,則檢查用戶權限,如果有,則根據PortalSettings,找到相應的模塊並顯示在左中右三個面板中,並設定題頭的標簽.(這樣一來,如果手動在地址欄輸入TabIndex和TabId,顯示時題頭與模塊可能會不一致,便不影響權限控製);如果沒有則轉向其它頁面.
//
如果是DesktopDefault.aspx頁面,則根據TabIndex設定題頭的標簽.再根據TabId找到相應的模塊並顯示.
//
不過如果手動在地址欄輸入TabIndex和TabId,顯示時題頭與模塊可能會不一致.
private
void
InitClass()
{
//
從HttpContext中獲取全局設置對像
PortalSettings portalSettings
=
(PortalSettings) HttpContext.Current.Items[
"
PortalSettings
"
];
//
設置標題欄
pageTitle.Text
=
portalSettings.PortalName;
//
Ensure that the visiting user has access to the current page
//
當當前用戶的角色不在當前活動標簽的可訪問角色中時,重定向到訪問錯誤頁
if
(PortalSecurity.IsInRoles(portalSettings.ActiveTab.AuthorizedRoles)
==
false
)
{
Response.Redirect(
"
~/Admin/AccessDenied.aspx
"
);
}
//
Dynamically inject a signin login module into the top left-hand corner
//
of the home page if the client is not yet authenticated
//
判斷是否顯示登陸信息(當用戶未驗證且顯示頁面為第一頁時)
if
((Request.IsAuthenticated
==
false
)
&&
(portalSettings.ActiveTab.TabIndex
==
0
))
{
LeftPane.Controls.Add(Page.LoadControl(
"
~/DesktopModules/SignIn.ascx
"
));
LeftPane.Visible
=
true
;
}
//
Dynamically Populate the Left, Center and Right pane sections of the portal page
//
當前標簽下的模塊數大於0時,分別在左中右三個方塊中顯示當前標簽下的模塊
if
(portalSettings.ActiveTab.Modules.Count
>
0
)
{
//
Loop through each entry in the configuration system for this tab
//
在當前標簽的模塊列表中依次讀取模塊
foreach
(ModuleSettings _moduleSettings
in
portalSettings.ActiveTab.Modules)
{
//
在頁面中找到存放指定控件的板塊(左中右)
Control parent
=
Page.FindControl(_moduleSettings.PaneName);
//
If no caching is specified, create the user control instance and dynamically
//
inject it into the page. Otherwise, create a cached module instance that
//
may or may not optionally inject the module into the tree
//
如果控件的緩存時間為0
if
((_moduleSettings.CacheTime)
==
0
)
{
//
構造用戶控件
PortalModuleControl portalModule
=
(PortalModuleControl) Page.LoadControl(_moduleSettings.DesktopSrc);
portalModule.PortalId
=
portalSettings.PortalId;
portalModule.ModuleConfiguration
=
_moduleSettings;
//
在指定板塊中加載控件
parent.Controls.Add(portalModule);
}
else
{
CachedPortalModuleControl portalModule
=
new
CachedPortalModuleControl();
portalModule.PortalId
=
portalSettings.PortalId;
portalModule.ModuleConfiguration
=
_moduleSettings;
parent.Controls.Add(portalModule);
}
//
Dynamically inject separator break between portal modules
//
加入控件之間的分隔符
parent.Controls.Add(
new
LiteralControl(
"
<
"
+
"
br
"
+
"
>
"
));
//
將存放控件的板塊置為可見
parent.Visible
=
true
;
}
}
}
--2.如果是其它頁面(基本是一些編輯頁面,明細表頁面),則在頁面的Load事件中判斷權限,並決定顯示頁面內容,還是轉向其它頁面.
//
如果是其它頁面(基本是一些編輯頁面,明細表頁面),則在頁面的Load事件中判斷權限.
private
void
Page_Load(
object
sender, System.EventArgs e)
{
//
所屬模塊Id
moduleId
=
Int32.Parse(Request.Params[
"
Mid
"
]);
//
驗證用戶是否可以修改指定模塊
if
(PortalSecurity.HasEditPermissions(moduleId)
==
false
)
{
Response.Redirect(
"
~/Admin/EditAccessDenied.aspx
"
);
}
//
項Id
if
(Request.Params[
"
ItemId
"
]
!=
null
)
{
itemId
=
Int32.Parse(Request.Params[
"
ItemId
"
]);
}
if
(Page.IsPostBack
==
false
)
{
if
(itemId
!=
0
)
{
//
獲取指定itemId的公告內容
AnnouncementsDB announcementDB
=
new
AnnouncementsDB();
SqlDataReader dr
=
announcementDB.GetSingleAnnouncement(itemId);
dr.Read();
int
dbModuleID
=
Convert.ToInt32(dr[
"
ModuleID
"
]);
if
(dbModuleID
!=
moduleId)
{
dr.Close();
Response.Redirect(
"
~/Admin/EditAccessDenied.aspx
"
);
}
TitleField.Text
=
(String) dr[
"
Title
"
];
MoreLinkField.Text
=
(String) dr[
"
MoreLink
"
];
MobileMoreField.Text
=
(String) dr[
"
MobileMoreLink
"
];
DescriptionField.Text
=
(String) dr[
"
Description
"
];
ExpireField.Text
=
((DateTime) dr[
"
ExpireDate
"
]).ToShortDateString();
CreatedBy.Text
=
(String) dr[
"
CreatedByUser
"
];
CreatedDate.Text
=
((DateTime) dr[
"
CreatedDate
"
]).ToShortDateString();
dr.Close();
}
else
{
//
默認有效期為一個星期
ExpireField.Text
=
DateTime.Today.AddDays(
7
).ToString(
"
yyyy-MM-dd
"
);
}
//
存儲上次請求頁Url
ViewState[
"
UrlReferrer
"
]
=
Request.UrlReferrer.ToString();
}
}
附:下面這個鏈接是關於DNN頁面生成原理的.我還沒有看DNN,不過我覺得他講的和Portal的原理差不多一樣.
http://www.cnblogs.com/genode/archive/2005/06/05/168235.html