當設計一個有多語系需求的程式時,除了UI上面的文字以外,另外像日期或幣值的顯示格式也都是要考量進來的議題。 例如:日元的顯示格式為 ¥123,456,而台幣的顯示格式為 NT$123,456;或者像日期的格式,美國使用的是 月/日/年 ,而日本使用的是 年/月/日。這些差異都會因為不同地區而有所不同,簡稱文化特性。 像這類狀況,因為我們無法預期未來會面對什麼樣的使用者需求,如果等系統開發完成後,才依照不同的地區性去做修改,那這個成本肯定會變的更大。 因此如何將資料依不同的文化特性格式化就變的很重要的課題。.Net Framework 提供了 System.Globalization 命名空間來幫助開發者解決這個問題。
2012年3月28日 星期三
2012年3月27日 星期二
寄送郵件
從 .Net2.0 開始, System.Net.Mail 命名空間提供開發者建立及傳送郵件訊息的相關方法。
- MailMessage:
這個類別是用來建立電子郵件。支援簡單的純文字、HTML格式的電子郵件訊息、以及不同檢視方式、編碼標準及附加檔。 - SmtpClient:
這個類別是用來寄送電子郵件。支援匿名網路連結、使用者驗證及SSL加密,另外也可以非同步寄送電子郵件,且允許使用者在寄送完成前取消寄送。
2012年3月23日 星期五
is 和 as
由於物件都是多型的,因此可以使用某個基底類別 (Base Class) 型別的變數來存放衍生型別 (Derived Type)。
若要存取衍生型別的方法,您必須將值轉型回衍生型別。
不過,在這種情況下嘗試進行簡單轉型卻會有擲回 InvalidCastException 的風險。
這就是 C# 提供 is 和 as 運算子的原因。
您可以使用這兩個運算子測試轉型能否成功,而不會擲回例外狀況 (Exception)。
as 運算子通常比較有效率,因為如果轉型能夠成功,它實際會傳回轉型值。
is 運算子卻只會傳回布林值,因此它可以用在只是要確定物件的型別而不必實際轉型的情況。
2012年3月21日 星期三
認識反射
Reflection ,一般稱為「反映」或「反射」,反射系統提供了瀏覽和檢測資料型別的功能。 通常,我們在使用型別資料的時候,順序大都是先取得型別參考,然後建立instance,再叫用其已知的屬性或方法。 Reflection 則可以動態載入組件,再檢測該型別中有哪些的屬性或方法,再進而呼叫使用。
例如,一些外掛(plug-in)的組件,系統開發階段根本不知道會遇到什麼外掛組件,那要如何存取型別? 通常就是透過 Reflection 動態載入組件,再將組件中的型別繫結給已知的物件,進而叫用其方法(method)或存取其屬性(property)。
反射組件的屬性
當我們設計一個組件時,除了類別的定義之外,還有一些額外的資訊是不包含在類別之中的,例如:版本編號,作者,公司資訊等等。 這些資訊統稱組件屬性,也就是前一節介紹的組件中繼資料。 欲編輯這些資訊可以在專案中開啟 AssemblyInfo 這個檔案,它就是用來儲存組件屬性的設定檔。(C#的檔案名稱為 AssemblyInfo.cs;VB的檔案名稱為 AssemblyInfo.vb)
反射組件的型別
前面章節,已經說明了組件與模組的用法,接下來要說明的是型別的反射。
取得型别 (Type)
要取得一個型別物件 ( Type ),可透過以下幾個方式:
- 由組件 ( Assembly ) 類別中的 Assembly.GetType 方法取得。
- 由模組 ( Module ) 類別中的 Module.GetType 方法取得。
- 由物件 ( Object ) 執行個體的 Object.GetType 方法取得。
- C# 的 typeof 運算子與 Visual Basic 的 GetType 運算子,都可取得型別的 Type 物件。
2012年3月20日 星期二
2012年3月16日 星期五
2012年3月14日 星期三
程式碼安全性
在Windows作業系統中,一般我們比較常用的安全系統是以使用者或角色為主的安全性機制(role-base security, RBS), 透過對使用者或角色的管理,達到權限控管的目的,這也是大家比較熟悉的權限管理機制。
如果當我們使用一個外來的組件來存取磁碟,為了確保它內部無法執行任何的惡意行為,你希望限定這個組件只能存取特定目錄,像這樣子的狀況,就無法使用 RBS 達到規範,而必須透過 CAS 管控到程式碼身上才有辨法。
組件的安全性
CAS 是一種用來限制資源被存取的機制,包括檔案、目錄、印表機、網路存取...。 .NET Framework 對每個可以被保護資源各提供一類別,定義在 System.Security.Permissions 命名空間裡。 每個類別都有各自的特定成員,藉以控制相關資源的使用權限。例如:
- GacIdentityPermission :defines the identity permission for files originating in the global assembly cache.
- PublisherIdentityPermission :represents the identity of a software publisher.
- DataProtectionPermission :controls the ability to access encrypted data and memory.
- StrongNameIdentityPermission :defines the identity permission for strong names
- FileIOPermission :
- IsolatedStoragePermission :
- ReflectionPermission :
- RegistryPermission :
- UIPermission :
- WebBrowserPermission :
- ZoneIdentityPermission :
- ...
方法的安全性
前一章節所描述的內容,是針對整個的組件(assembly),進行 CAS 設定以保護組件的安全。 除此之外,也可以針對組件的方法 (method) 做各別的 CAS 設定以保護方法 的安全。 建立方法安全性時,有二種方式:宣告式 (Declaratively) 和命令式 (Imperatively) 。 使用宣告式時,編譯器會在程式碼執行前就做安全性檢查; 使用命令式時,則在程式碼執行中才做安全性檢查,並控制檢查失敗的處理作業。
方法使用權限請求的種類
設定方法的使用權限請求,也是透過 SecurityAction 列舉型別的設定,就可以請求特定的使用權限。 前一章節有介紹到,在 CAS 組件宣告時, SecurityAction 共有三種設定值,但是在 CAS 方法宣告中,則有六種不同的權限請求設定值:
- Demand ( 要求 ) :堆疊中的所有呼叫端都要有權限。
- PermitOnly :指明本方法中,僅可以執行的權限,用來降低權限。
- Assert ( 判斷提示 ) :告訴 runtime ,只要此呼叫端有權限即可,可以忽略再往上層的檢查。
- Deny ( 拒絕 ) :拒絕某個權限,用來降低權限。
- LinkDemand ( 連結要求 ) :只要立即呼叫端(直接呼叫的那個呼叫端)有權限即可。
- InheritanceDemand ( 繼承要求 ) :。
注意1:
其中的 LinkDmand 和 InheritanceDemand 二項,只能用在 Declaratively ,不能用在 Imperatively 。
注意2:
當某個方法的屬性值被設成 Demand 或 LinkDemand ,CAS 並不是檢查目前這個方法的使用權限,而是檢查呼叫的那個方法的使用權限。 Demand 要求所有呼叫端都要檢查;LinkDemand 要求只要檢查直接呼叫端即可。
事件 (Event)
事件說明
什麼是事件
事件是物件的一種機制,當物件在某種條件狀況下,該事件就會被引發。若客戶端程式有訂閱這個事件,該物件就會送出事件引發訊息。
傳送事件的類別稱為發行者(Publisher)-> Raise Event
接收事件的類別稱為訂閱者(Subscriber)-> Handle Event
事件是物件的一種機制,比較學術的說法則是,事件是一種特殊的委派方法。通常可由二個方面來看事件:發行者和訂閱者。
- 發行者(Publisher):引發事件的類別 (Raise Event Class)
- 訂閱者(Subscriber):接收事件的類別 (Handle Event Class)
委派 (Delegate)
什麼是委派
話說委派
在設計一個類別的時候,我們可能必需在某些情況下去執行某些事情,但又不想/無法在類別裡寫死處理的方法,這時就要用到委派。 我們僅在類別裡定義一個特定的簽名(signature),指出要執行的方法的樣子(樣子指的就參數列與回傳值的型別),至於該方法叫什麼名字,內容如何,則由呼叫端於呼叫時自行決定。
舉個例好了:
假設你在設計一個警報器,你在這個類別上加上了一個"警鈴響了"事件,事件發生時,這個類別啟動自動處理模式,例如,撥打119或撥打110或通知老闆...。 但是你在設計時,根本不知道使用者要如何處理,所以這部分就可以留待使用者自行撰寫處理方法。
也就是說,在設計類別時,可能會碰到某個方法在執行時需要額外處理,但是你無法將這部分的處理寫死在類別裡,此時就得將這個部分「外包」給呼叫端自行處理。 而客戶端必須事先提供一個處理函式,等到類別的方法要執行的時候,就會回頭去呼叫(callback)那個客戶端事先指定的處理函式。這個處理函式就稱為「委派方法」。
2012年3月9日 星期五
Common Language Runtime
通用語言執行平台(Common Language Runtime,簡稱CLR)是微軟為.NET的虛擬機器所選用的名稱。 這是通用語言架構(簡稱CLI)的微軟實作版本,它定義了一個程式碼執行的環境。 CLR執行一種稱為通用中間語言的位元組碼,就是 Microsoft Intermediate Language (MSIL)。這個是微軟的通用中間語言實作版本。
如何變更 SQL Server 預設的資料檔路徑與備份檔路徑
在操作 SSMS 時,常會碰到二個預設目錄,一個是在新增資料庫時,資料庫存放的目錄,一個是在備份資料庫時,備份檔存放的目錄。 由於系統使用的預設的目錄為 C:\Program Files\Microsoft SQL Server\MSSQL10_50.W7_SQLSVR_2008\MSSQL\Backup\ , 這通常不是大家慣於使用的位置,每次新增或備份資料庫的時候,就得手動再切換到自已要使用的目錄。 如果你跟我一樣覺得這樣子很麻煩的話,底下的示範就是說明如何變更這個預設目錄的值,讓使用 SSMS 時可以方便一點點。
2012年3月7日 星期三
XML Menu
在設計視窗程式時,常常會使用到 MenuStrip 控制項來設計功能選單。 不過有時候選單項目無法在設計階段就決定,必須等到執行階段才能決定,這時候就必須利用到動態載入選單的技巧。
這篇文章,將使用 XML 文件來規範選單的內容,再透過反射的技巧,開啟要執行的表單。
使用 Div 做排版
使用 <div> 做排版
display 屬性
- 區塊模式(display:block):元素會以區塊方式呈現,除非設定 position 或 float。
- 行內模式(display:inline):所有文字或圖片均不換行,也就是全部都會是同一行的意思。
2012年3月6日 星期二
建立AppDomain
設定AppDomain組態
前言
當建立一個 AppDomain 時,我們也可以修改它的屬性設定以適應要載入的組件。 例如,當我們想載入一個不明的組件到某個 AppDomain ,我們可以建立一個較小使用權限的 AppDomain ,以降低安全性弱點的風險。 AppDomain 不僅可以提供隔離單位,還可以降低被攻擊時所可能造成的損害。 尤其當呼叫組件執行時,適當的限制 AppDomain 的權限,將可大大減少惡意行為風險的發生。 例如,當我們使用一個外購的組件進行指定目錄的備份監控,要如何肯定這個程式不會讀取其他目錄的資料呢?或者如何提防它是否會透過網路將資料外傳呢? 反之,當我們設計一個組件,若沒有做任何安全性的限制,它會不會變成漏洞,反而被其他組件拿來當成跳板,執行不該有的行為呢?
Windows Service
Microsoft Windows 服務,也就是先前的 NT 服務,可讓您建立長期執行的應用程式,在應用程式本身的 Windows 工作階段 (Session) 中執行。 這些服務可以在電腦啟動時自動啟動,也可以暫停或重新啟動,都不會顯示任何使用者介面。 這些功能使得服務非常適合在伺服器中使用,或每當需要不干擾使用同一部電腦之其他使用者的長期執行功能時使用。 您也可以在不同於登入使用者或預設電腦帳戶的特定使用者帳戶的安全性內容下執行服務。