Duwamish代碼分析篇
Written by: Rickie Lee
Nov. 02, 2004
繼續前面的2篇POST《Duwamish架構分析篇》和《Duwamish部署方案篇》,這裏在代碼層次上分析Duwamish 7.0範例,主要目的是解析Duwamish範例中值得推薦的編碼風格和提煉出可以重用的代碼或Class。
1,讀取配置文件類-SystemFramework/ApplicationConfiguration.cs
ApplicationConfiguration類用來讀取web.config文件中自定義section的配置信息,初始化一些基本設置。
ApplicationConfiguration類實現IconfigurationSectionHandler接口,並需要實現[C#]
object Create(
object parent,
object configContext,
XmlNode section
)方法,以分析配置節的 XML。返回的對象被添加到配置集合中,並通過 GetConfig 訪問。
部分代碼片斷解釋:
(1)Code Snippet 1 – ApplicationConfiguration. OnApplicationStart()方法
public static void OnApplicationStart(String myAppPath)
{
appRoot = myAppPath;
System.Configuration.ConfigurationSettings.GetConfig("ApplicationConfiguration");
System.Configuration.ConfigurationSettings.GetConfig("DuwamishConfiguration");
System.Configuration.ConfigurationSettings.GetConfig("SourceViewer");
}
ConfigurationSettings 類還提供了一個公共方法ConfigurationSettings.GetConfig() 用於返回用戶定義的配置節的配置設置,傳入的參數section name,如"ApplicationConfiguration",表示要讀取的配置節。
NameValueCollection nv=new NameValueCollection();
//實例化NameValueCollection 類對象
nv=(NameValueCollection)ConfigurationSettings.GetConfig("ApplicationConfiguration ");
//返回用戶定義的配置節的設置
return nv["SystemFramework.Tracing.Enabled"].ToString();
//返回特定鍵值,如SystemFramework.Tracing.Enabled
不過,ConfigurationSettings.GetConfig()方法在調用時,自動調用Create()方法,可以看到ApplicationConfiguration.Create()方法正是用來讀取指定section的配置,並初始化設置參數。
Global.asax 的 Application_OnStart 事件處理程序向 SystemFramework 的ApplicationConfiguration 類 OnApplicationStart 方法發出調用,正是上述的代碼片斷。
(2)Code Snippet 2 - Global.asax中Application_OnStart()方法
void Application_OnStart()
{
ApplicationConfiguration.OnApplicationStart(Context.Server.MapPath( Context.Request.ApplicationPath ));
string configPath = Path.Combine(Context.Server.MapPath( Context.Request.ApplicationPath ),"remotingclient.cfg");
if(File.Exists(configPath))
RemotingConfiguration.Configure(configPath);
}
該方法肩負二大任務:(1)調用ApplicationConfiguration.OnApplicationStart()方法,並傳入application的根目錄(Root Directory)。(2)檢測Client端的remoting配置文件是否存在(其實是web server端),如果存在,則讀取並初始化remoting配置信息,如配置通道Channel等等,詳見《Duwamish部署方案篇》。
2,讀取web.config中Duwamish相關的一些配置-Common/DuwamishConfiguration.cs
Common/DuwamishConfiguration.cs也實現IconfigurationSectionHandler接口,與SystemFramework/ApplicationConfiguration.cs類相似。
DuwamishConfiguration配置節包括如下一些配置信息:
Database connection string(Database連接串)Duwamish.DataAccess.ConnectionString,是否允許頁面緩存Duwamish.Web.EnablePageCache,頁面緩存過期時間Duwamish.Web.PageCacheExpiresInSeconds,是否允許SSL連接Duwamish.Web.EnableSsl等等。
如上所述,調用DuwamishConfiguration Class 是由SystemFramework/ApplicationConfiguration.cs的OnApplicationStart()方法完成的:
System.Configuration.ConfigurationSettings.GetConfig("DuwamishConfiguration");
看看頁面緩存配置在web page中如何使用的(web/book.aspx.cs文件爲例):
//
// If everything succeeded, then enable page caching as indicated
// by the current application configuration.
//
if ( DuwamishConfiguration.EnablePageCache )
{
//Enable Page Caching...
Response.Cache.SetExpires ( DateTime.Now.AddSeconds(DuwamishConfiguration.PageCacheExpiresInSeconds));
Response.Cache.SetCacheability(HttpCacheability.Public);
}
在Page_Load事件中最後判斷是否允許頁面緩存。
3,驗證數據合法性類-SystemFramework/ApplicationAssert.cs
SystemFramework/ApplicationAssert.cs Class用來進行錯誤檢測,並調用SystemFramework/ApplicationLog.cs Class記錄錯誤日誌。
學習其中的部分代碼片斷:
(1)Code Snippet 1 – Check Method
[ConditionalAttribute("DEBUG")]
public static void Check(bool condition, String errorText, int lineNumber)
{
if ( !condition )
{
String detailMessage = String.Empty;
StringBuilder strBuilder;
GenerateStackTrace(lineNumber, out detailMessage);
strBuilder = new StringBuilder();
strBuilder.Append("Assert: ").Append("/r/n").Append(errorText).Append("/r/n").Append(detailMessage);
ApplicationLog.WriteWarning(strBuilder.ToString());
System.Diagnostics.Debug.Fail(errorText, detailMessage);
}
}
[ConditionalAttribute("DEBUG")]定義Check()方法爲conditional method,如果預處理符號(preprocessor symbol)沒有定義,compiler不僅忽略該方法,而且忽略對該方法的調用,和#if DEBUG / #else / #endif有些類似。
該方法用來判斷條件condition是否爲true,如果爲false,則調用SystemFramework/ApplicationLog.WriteWarning()方法記錄錯誤日誌。
(2)Code Snippet 2 – CheckCondition Method
public static void CheckCondition(bool condition, String errorText, int lineNumber)
{
//Test the condition
if ( !condition )
{
//Assert and throw if the condition is not met
String detailMessage;
GenerateStackTrace(lineNumber, out detailMessage);
Debug.Fail(errorText, detailMessage);
throw new ApplicationException(errorText);
}
}
該方法一般用來在進行前置條件判斷,如condition爲false,則拋出exception。
4,log日誌類-SystemFramework/ApplicationLog.cs
ApplicationLog 類實現 Duwamish 7.0 中的記錄和跟蹤。Web.Config 文件中的配置設置確定是輸出到 EventLog 文件、跟蹤日誌文件還是兩者。下面是 Web.Config 文件中的 <ApplicationConfiguration> 節,它指定 EventLog 設置:
<ApplicationConfiguration>
<!-- Event log settings -->
<add key="SystemFramework.EventLog.Enabled" value="True" />
<add key="SystemFramework.EventLog.Machine" value="." />
<add key="SystemFramework.EventLog.SourceName" value="Duwamish7" />
<add key="SystemFramework.EventLog.LogLevel" value="1" />
<!-- Use the standard TraceLevel values:
0 = Off
1 = Error
2 = Warning
3 = Info
4 = Verbose -->
Web.Config 文件的同一節還指定跟蹤配置。Duwamish 7.0 跟蹤日誌的默認位置是:[安裝 Visual Studio .NET 的驅動器號]:/Program Files/Microsoft Visual Studio .NET 2003/Enterprise Samples/Duwamish 7.0 CS/Web/DuwamishTrace.txt
在實際的應用系統開發中,用來提供Log功能的類應該比這個ApplicationLog類要好,這樣就不去分析了,如Microsoft Exception Management Application Block就不錯。
5,Web.config配置文件-使用Web.congfig文件存儲application設置
Duwamish 7.0 通過使用 Forms 身份驗證來實現安全性。Forms 身份驗證將未經授權的用戶重定向到Web 窗體,該窗體提示用戶輸入其電子郵件地址和密碼。
(1)配置 Forms 身份驗證
Web.config 文件中的設置配置 Forms 身份驗證。對於 Duwamish 7.0,Web.Config 文件按如下所述指定 Forms 身份驗證的使用:
<authentication mode="Forms">
<forms name=".ADUAUTH" loginUrl="secure/logon.aspx" protection="All">
</forms>
</authentication>
<authorization>
<allow users="*" />
</authorization>
authentication元素只能在計算機、站點或應用程序級別聲明。如果試圖在配置文件中的子目錄或頁級別上進行聲明,則將產生分析器錯誤信息。
如上所示,Web.Config 將 .ADUAUTH 指定爲身份驗證 Cookie 的名稱。當用戶請求受限資源時,公共語言運行庫將未經授權的用戶重定向到在上面的 Web.Config 設置中指定的Login.aspx。protection="All" 設置指定應用程序使用數據驗證和加密來保護 Cookie。若要進一步限制資源,Duwamish 7.0 會將安全資源放置到名爲 secure 的子文件夾中並使用額外的 Web.Config 文件(在secure文件夾),在該文件中指定只有經過身份驗證的用戶纔可訪問該子文件夾的內容。
<authorization>
<deny users="?" />
<allow users="*" />
</authorization>
<deny users="?" /> 標記指定拒絕對所有匿名用戶的訪問。<allow users="*" /> 標籤允許訪問所有已驗證身份的用戶。
經過secure/logon.aspx認證通過的請求,重新定向最初的URL。
// 將已驗證身份的用戶重定向回最初請求的 URL。
FormsAuthentication.RedirectFromLoginPage("*", false);
(2)用戶定義的配置節
<configSections>
<section name="ApplicationConfiguration" type="Duwamish7.SystemFramework.ApplicationConfiguration, Duwamish7.SystemFramework" />
<section name="DuwamishConfiguration" type="Duwamish7.Common.DuwamishConfiguration, Duwamish7.Common" />
<section name="SourceViewer" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>
section元素包含配置節聲明,name 指定配置節的名稱,type 指定從配置文件中讀取節的配置節處理程序類的名稱。配置節處理程序(即實現 IConfigurationSectionHandler 接口的類)讀取設置。
上面定義了3個配置節處理程序:Duwamish7.SystemFramework.ApplicationConfiguration
Duwamish7.Common.DuwamishConfiguration
System.Configuration.NameValueSectionHandler
前面兩個配置節處理程序是由application提供的,後面的System.Configuration.NameValueSectionHandler是.Net Framework提供的,該類也實現了IconfigurationSectionHandler接口,用來提供配置節中的名稱/值對配置信息。
6,web/PageBase.cs基類
最後談談web/PageBase.cs基類吧,所有 Duwamish 7.0 中的所有web頁都繼承名爲 PageBase 的基類,該類實現 Duwamish 7.0 應用程序的 ASP.Net 頁中使用的常見屬性和方法,這種設計方法值得推薦。
Code Snippet分析:
/// <summary>
/// Handles errors that may be encountered when displaying this page.
/// <param name="e">An EventArgs that contains the event data.</param>
/// </summary>
protected override void OnError(EventArgs e)
{
ApplicationLog.WriteError(ApplicationLog.FormatException(Server.GetLastError(), UNHANDLED_EXCEPTION));
base.OnError(e);
}
重載OnError方法,使application遭遇到未處理錯誤的時候,自動調用ApplicationLog.WriteError()來記錄錯誤日誌。
另外,覺得Duwamish的password處理有些特別,是以byte形式存放在Database中,避免明文的方式,以提高安全性(將在《Duwamish密碼分析篇》進行中分析)。
轉自:http://www.cnblogs.com/rickie/archive/2004/11/03/59897.html