天天看點

.net開發過程中,錯誤集錦 2007年7月10日 System.Data.OracleClient 需要 Oracle 用戶端軟體 8.1.7 或更高版本 2007年6月25日 2007年6月11日 2007年6月8日 2007年6月6日 應用程式結構 向應用程式中添加預定作業生成Web服務生成Windows服務擴充流程層以處理預定作業作業計時資訊檢索和設定作業計時資訊調用作業計時存儲過程處理預定作業小結作者簡介資料交換中心的方案設計 2007年5月31日

.net開發過程中,錯誤集錦 2007年7月10日 System.Data.OracleClient 需要 Oracle 用戶端軟體 8.1.7 或更高版本 2007年6月25日 2007年6月11日 2007年6月8日 2007年6月6日 應用程式結構 向應用程式中添加預定作業生成Web服務生成Windows服務擴充流程層以處理預定作業作業計時資訊檢索和設定作業計時資訊調用作業計時存儲過程處理預定作業小結作者簡介資料交換中心的方案設計 2007年5月31日
2007年7月10日

開發過程中,錯誤集錦。

寫這個東東的目的,主要是上班那不能夠上網,回家後總結出來弄到日志本裡面的.順便鄙視下移動,對廠家這麼刻薄,不能上網,不能帶水進去喝,最氣人的是,進出大樓,冰火兩重天,20度左右的溫度.又要項目趕進度,又天天有上司來視察,天天把廠家掃地出門溜達去.

2007年 6月 移動項目:

1:vs2005上安裝vss2005後,不能夠顯示源代碼管理

(http://www.cnblogs.com/SGSoft/archive/2007/06/12/780351.html)

A:打開菜單中的 Tools->Options 選擇 SourceControl->Plug-ins

設定為

“Microsoft Visual SourceSafe "

 "Microsoft Visual SourceSafe (Internet)"

選擇第一項,好象是以tcp方式連接配接資料庫伺服器,如果是後面一項,則要求輸入資料庫伺服器上的webserverce

如果沒有這兩個選項,則運作下面的指令:

regsvr32 "C:/Program Files/Microsoft Visual SourceSafe/ssscc.dll"

regsvr32 "C:/Program Files/Microsoft Visual SourceSafe/ssapi.dll"

regsvr32 "C:/Program Files/Microsoft Visual SourceSafe/tdnamespaceextension.dll"

regsvr32 "C:/Program Files/Microsoft Visual SourceSafe/RemoteVssScc.DLL"

【假定你的VSS安裝到C槽】

重起 VS2005,在上面的位置就能看到選項了。

2:vs2005編譯釋出成多個dll

解決方案:安裝一個 叫 WebApplicationProjectSetup.msi 的程式就可解決

但是,該程式有兩個版本,一個大小為905kb的會在編譯後中文顯示亂碼。安裝919kb的就可以解決這個問題。

該東西非常的好用,呵呵。

但是,這個東西經常的會出現一點點問題,

 aspnet_megre.exe 已退出,.代碼為-1

出現這個問題,呵呵,看了下網上的說明,大多是因為webserver的原因.

導緻這個問題的原因是在[webmethod(description="這個裡面是中文解釋")]

本人的解決方法,要麼是把 這句中文不要, 要麼就是後面加空格,反正,能夠實作了.

還有個問題,不知道是不是這個錯誤,就是釋出的時候, 儲存釋出網站dll的哪個檔案的原因, bin目錄不能夠通路,呵呵

我一般遇到這個問題,就是從新弄個檔案夾, 換個釋出的名字,就能夠搞定.

2007年6月18号

3:Cannot convert type 'ASP.login_aspx' to 'System.Web.UI.WebControls.Login'

這個問題出現在vs2005釋出後

發現問題主要還是出在Asp2.0下Login.Aspx頁面和VS2005登陸控件沖突。

解決方案:

  打開Login.aspx.cs檔案,把

public partial class Login : System.Web.UI.Page

  改成

public partial class myLogin : System.Web.UI.Page

  當然你也可以改LoginWeb、UserLogin之類的,反正不能用Login

  打開Login.aspx,把最頂上的那句Inherits="Login"改成Inherits="myLogin"

  釋出後正常

以後自己取名字的時候,象這樣的類名等等,盡量不取和vs一樣的。

4:Client found response content type of 'text/html', but expected 'text/xml'.

這個問題,出現在調用webserver的時候,呵呵,出現這個錯誤,當然是webserver那出錯了,我程式出現該錯誤的時候,是引用沒找到,這個好解決,但是,看見網上的别人出現這個錯誤的解釋,反正,看不懂,呵呵,實在是搞不明白,為什麼難得見的錯誤的解釋,都是英文的呢?

5:The 'OraOLEDB.Oracle.1' provider is not registered on the local machine.

這種情況有3種可能的原因(http://www.cnblogs.com/tongzhenhua/archive/2004/06/18/16714.html)

1.裝Oracle 的機器是不是NTFS的?如果是的話,将/Ora81下的BIN的權限,全部放開,給所有使用者。

(不然在B/S結構下會因為沒有權限通路目錄而報這個錯誤)

2.如果資料庫伺服器是Oracle816的。在伺服器的那台機器上找Ora81/network/ADMIN下的sqlnet.ora檔案,把裡面的

SQLNET.AUTHENTICATION_SERVICES= (NTS)改成

SQLNET.AUTHENTICATION_SERVICES= (NONE)

(這種會造成某些機器上報驅動初始化失敗的錯誤,在用OracleClient下出現過一次)

3.如果以上都沒有解決問題。可以考慮是不是系統資料庫裡的注冊真的丢失了。(可能性比較小,windows還是比較安全的)

regsvr32 ../ORACLE_HOME/bin/OraOLEDB.dll

再不行可以重裝一下用戶端試試。

解決方法如下:(http://ms.mblogger.cn/web1999/posts/18148.aspx)

到ORACLE_HOME目錄,如c:/Oracle/Ora92

點選滑鼠右鍵->屬性->安全,

對ASP.NET 帳戶賦予允許讀、執行權限,并在“進階”中保證該目錄的子目錄、檔案都繼承這些屬性,确定。

重新注冊oraoledb.dll:regsvr32 $/oracle/ora92/bin/oraoledb.dll

今天非常的高興,釋出一個網站居然能夠出現這麼多的錯誤,呵呵.

6:oracle 10g+vs2005+oracleClient.dll出現的問題

出錯情況介紹:

個人的機器上裝的是:oracle9i,伺服器用的是oracle10g,用的都是一個oracleCclient.dll,在自己機器上運作的非常的好,能夠得到資料,釋出程式到伺服器上,就不能夠得到結果,同時,同一個資料庫操作類,在winform上執行同樣的查詢能夠得到結果,在webform上卻不能夠得到結果.

首先,出現的錯誤是:Could not create an environment: OCIEnvCreate returned -1

解決方案一:

              主要是将oracle主目錄oracle/的讀寫權限賦予asp.net或者是IUSER_..和IWAM_..,重新開機計算機。

解決二:

打開在IIS中的WEB屬性--主目錄--執行權限【改為-腳本和可執行檔案】;

-應用程式池【改為-MSSharePointAppPool】,重新整理OK;

解決三:

檔案夾權限可以不用管。

設定ORACLE_HOME變量的方法如下

控制台>>系統>>進階>>環境變量>>系統變量>>建立系統變量

變量名寫ORACLE_HOME

變量值添實際的ORACLE_HOME路徑,在系統資料庫中有

個人按照上面的做了,出現另外的一個錯誤

System.Data.OracleClient 需要 Oracle 用戶端軟體 8.1.7 或更高版本

這個問題忘記是怎麼搞定的了,也許還是改權限吧,反正,伺服器從啟後,這個問題就沒在出現,呵呵.

7 oracle 中操作blob + c#

OleDbCommand cmd1 = new OleDbCommand(" INSERT INTO BLOB (PHOTO) VALUES ( ? )",cn);

     cmd1.Parameters.Add("PHOTO",OleDbType.Binary);

     cmd1.Parameters["PHOTO"].Value = MyData;

cmd.CommandText = " insert into xlutest ( hhhh ) values (:hhhh) ";

   cmd.Parameters.Add("hhhh",System.Data.OleDb.OleDbType.Binary,expbyte.Length);

   cmd.Parameters [0].Value = expbyte;

 8 無法在“”已存在的情況下建立/影像複制該檔案

解決方法:重新編譯整個項目 或者重新開機電腦,呵呵

9 RegisterStartupScript 已過時

改為Page.ClientScript.RegisterStartupScript

10 由于目标機器積極拒絕,無法連接配接

vs2005裡面,添加web引用的時候,預設的ulr會帶上端口号,如:localhost:2473,是以,在添加完引用後, 用localhost替換掉所有的localhost:2473,在編譯就行了

11 沒有 aspnet 使用者 

安裝一.net控件的時候,顯示沒有aspnet使用者。實作方法:

aspnet_regiis -i

 12 怎樣得到目前日前的月份(月份為英文月的全稱,比如July)

DateTime.Now.ToString("MMMM",new System.Globalization.CultureInfo("en-us"))

DateTime.Now.ToString("MMMM",DateTimeFormatInfo.InvariantInfo )

posted @ 2007-07-10 15:28 wangyan 閱讀(81) | 評論 (0) |  編輯  收藏  

.net開發過程中,錯誤集錦 2007年7月10日 System.Data.OracleClient 需要 Oracle 用戶端軟體 8.1.7 或更高版本 2007年6月25日 2007年6月11日 2007年6月8日 2007年6月6日 應用程式結構 向應用程式中添加預定作業生成Web服務生成Windows服務擴充流程層以處理預定作業作業計時資訊檢索和設定作業計時資訊調用作業計時存儲過程處理預定作業小結作者簡介資料交換中心的方案設計 2007年5月31日
2007年6月25日

IE浏覽器無法檢視源檔案原因及應用技巧 問:無論是使用Outlook還是IE,點選滑鼠右鍵,在彈出的快捷菜單中都會有“檢視源檔案”這一選項,奇怪的是,在我的電腦上竟然無法顯示該郵件或網頁的源檔案,雖然這并沒有影響到該軟體的正常使用。請問,這是不是因為我之前安裝了Microsoft的某個更新版本或更新檔程式而導緻該功能自動屏蔽了呢?有沒有辦法可以重新啟動該功能?要知道,無法檢視源檔案,這可是一件很麻煩的事情,特别是對于Outlook使用者而言,更是如此。就拿我本人來說吧,每次收到的郵件中如果出現了URL連結,我都習慣先檢視一下它的源檔案,确定了它的安全之後,才會點選它。   

  答:如果你不太确定收件箱中的某封電子郵件或某個需要浏覽的網站頁面是否附帶了病毒時,可以通過“檢視源檔案”的方式,檢視背景HTML源代碼。如果源檔案中顯示的URL與真實的連結無法比對,那說明該郵件或網頁有問題。 如果“檢視源檔案”這一功能無法使用了,确實是件很麻煩的事情。導緻該問題出現的原因有很多,下面将一一列舉:   

  第一類情況是,當浏覽器的緩存被裝滿時,“檢視源檔案”功能将失效。如果你想确定自己的電腦是否屬于這類情況,可以點選IE的“工具”菜單中的“Internet選項” “正常”标簽,然後,再點選“Internet臨時檔案”一欄中的“删除檔案”按鈕。   

  第二類情況,當你打開某些特殊的浏覽器視窗(比如說用JavaScript腳本語言編寫的網頁)時,“檢視源檔案”功能也會失效。如果你在浏覽任何網頁時,都無法“檢視源檔案”,那就不屬于這類情況。   

  第三類情況,當一個網頁還沒有被完全加載到桌面時,“檢視源檔案”功能也是不能使用的(在這種狀态下,“檔案”菜單中的“另存為”選項也是屏蔽的)。這也算不上是真正的問題。   

  第四類情況,檢視Windows檔案夾,如果找不到Notepad.exe,将會導緻“檢視源檔案”功能無法使用。   

  第五類情況,如果TEMP(或TMP)環境變量指向某一個不存在的檔案夾,也會導緻“檢視源檔案”功能無法使用。打開指令提示符(command prompt)視窗,鍵入SET TEMP(或SET TMP),就可以檢視到這些變量的值。   

  第六類情況,通過系統資料庫設定也可以限定指令行的有效性。首先,點選“開始”菜單,在運作對話框中鍵入“REGEDIT”,調出系統資料庫編輯器,點選“HKEY_CURRENT_USERSoftware PoliciesMicrosoftInternet Explorer Restrictions”,在右邊的窗格中找到一個名為NoViewSource的值,如果目前的數值資料設定為1,則輕按兩下它,将數值資料更改為0。   

  第七類情況,通過檢視系統資料庫設定,你還會發現:如果指定的調用程式不正确,也将導緻“檢視源檔案”功能失靈。調出系統資料庫編輯器,點選“HKEY_LOCAL_MACHINESoftware MicrosoftInternet ExplorerView Source EditorEditor Name”,如果該鍵存在的話,右邊窗格中所顯示的預設的“數值名稱”應該是記事本程式的完整路徑,一般以“C:windowsnotepad.exe”的形式表示。如果該鍵不存在,先核實記事本程式的正确位置,然後輕按兩下預設鍵值,修改錯誤路徑。   

  第八類情況,組政策的設定也有可能會屏蔽“檢視源檔案”這一菜單項。從“開始”菜單中調出“運作”對話框,鍵入GPEDIT.MSC。如果桌面上彈出一個提示框,提示該檔案名不正确,則說明“檢視源檔案”功能的失效與組政策的設定無關;否則,桌面上将會彈出一個“組政策編輯器”視窗,點選“User ConfigurationAdministr-ativeTemplatesWindows ComponentsInternet ExplorerBrowser”,在右邊的窗格中找到View menu: Disable Source menu,如果這個鍵值被設定為“Enabled”,則将它更改為“Disabled”。   

  注意,上面介紹的第一類情況(即由于IE所儲存的Internet臨時檔案過多而造成“檢視源檔案”功能失靈)是最常見的(如圖)。如果删除了所有脫機内容之後,該功能仍然無法使用,你再依次檢查後面所介紹的幾種可能性,直到問題消除為止。 

  源檔案檢視小技巧 

  1、檢視帶有架構(Frame)的網頁源碼  

  如果有的網頁中使用了架構(Frame),或者使用了多視窗,那麼利用IE菜單上的指令就隻能得到架構設定的源碼,是以無法檢視網頁設計的細節。此時久需要變通一下方法。将滑鼠指針移到網頁中非連結的位置,單擊滑鼠右鍵,在彈出的視窗中選擇“檢視源檔案”功能。需要檢視哪個視窗的源檔案,就将滑鼠指針指向哪個視窗,再通過點選右鍵菜單來進行操作。 

  2、使用特殊的指令  

  其實,最簡單的方法大概是利用指令了。它的格式為: view-source:http://X.X.X,此時,網頁不會顯示,卻會出現一個顯示網頁源碼的文本框。  

  對于帶有架構的網頁,可以首先找到架構内某個感興趣的網頁名稱,然後再通過該指令檢視架構内的網頁源碼。  

  3、利用網頁編輯器  

  上面的方法固然有用,但是,有的網頁保密工作做的非常周全,首先它使用了多視窗的Frame頁,讓IE菜單上的源碼檢視功能不能發揮作用,接着它又将滑鼠的右鍵屏蔽了,怎麼辦呢?這時候我們可以考慮使用網頁編輯器來檢視網頁源碼。  

  以IE為例,具體操作方法如下:單擊待檢視源檔案的Frame視窗,利用滑鼠的拖動來選擇要檢視的部分,如果滑鼠徹底被屏蔽,也可以選擇IE菜單上的“編輯”→“全選”。然後單擊“編輯”→“複制”。接着打開FrontPage 網頁編輯工具,點選“檔案”→“建立”,然後選擇“編輯”→“粘貼”。這時待檢視的網頁或其中的一部分内容便被複制了過來,再利用FrontPage 中所見即所得的特性便可檢視其源碼了。使用此方法雖然比較繁瑣,但是卻有很有效。首先,這種方法不受任何限制,對所有的網頁都适用,此外,利用這種方法還可以有針對性地檢視指定的内容。有時一個網頁的源檔案可能很大,從中找到指定的源代碼象是大海撈針。而用此方法可輕而易舉地找到所需要的源代碼。  

  如果你嫌麻煩,我們也可以采用另外的方法。首先,将帶有Frame視窗的網頁“令存”,要記住,存的時候要令存為“網頁,全部”的形式,存好之後,你就可以在存好的網頁目錄中找到幾個Frame視窗中子視窗的HTML檔案,此時再用FrontPage等網頁編輯工具将其打開即可檢視網頁源碼了。 

posted @ 2007-06-25 15:45 wangyan 閱讀(7) | 評論 (0) |  編輯  收藏   什麼是測試驅動開發?(TDD)

一、什麼是TDD

      簡單的說,即在寫任何功能代碼之前,先寫它的測試代碼。具體步驟:

          ·根據需要編寫一個測試用例

          ·編寫功能代碼,以讓剛才的測試用例通過

          ·逐漸補充測試用例

          ·修改功能代碼使新增的測試用例和原來的都通過

          ·重構,包括功能代碼和測試用例

二、為什麼使用TDD

      提高代碼品質。由于功能代碼的高品質和完善的測試用例集,增強了開發者信心,進而赢得他人信任。

      改進設計。TDD保證了功能代碼的可測試性,降低了耦合度,改善元件對象模型,使設計在開發過程中逐漸完善和改進。

      為功能代碼提供了良好的文檔,并能維護代碼和文檔的同步。靈活宣言主張:能夠運作的軟體勝過面面俱到的文檔。測試用例集就是一份準備可靠,且能運作的文檔。

      在一定程度上可代替程式調試。當每個單元測試關注每一個具體功能時,問題被更早和更好地避免。另外調試是手動而不可重複,TDD的測試用例集則是自動可回歸的。

      有效的品質控制和項目管理。對管理者來說,通過單元測試每日建構的結果,每天都清楚的知道項目的品質和開發進度

三、TDD是測試,更是設計

       當開始寫單元測試代碼時,其實也正在開發。在編寫功能代碼前,站在功能代碼的使用者角度設計測試用例,運用針對接口程式設計等原則降低耦合度,改進設計。由此可見,TDD也是面向對象的分析,設計和開發方法。在貫徹TDD的開發過程中,對于每個類分别進行測試,對于每部分都進行簡單設計,頻繁重構,最終形成了一整套可運作的測試用例集,TDD展現持續改進的過程,是一種增量式設計。

        TDD(Test Driven Development),是一種測試技術,更是一種設計方法。其重心不在Test,而在于Development,是一種以意圖來驅動的軟體開發方法——意圖程式設計。

posted @ 2007-06-25 10:33 wangyan 閱讀(4) | 評論 (0) |  編輯  收藏  

.net開發過程中,錯誤集錦 2007年7月10日 System.Data.OracleClient 需要 Oracle 用戶端軟體 8.1.7 或更高版本 2007年6月25日 2007年6月11日 2007年6月8日 2007年6月6日 應用程式結構 向應用程式中添加預定作業生成Web服務生成Windows服務擴充流程層以處理預定作業作業計時資訊檢索和設定作業計時資訊調用作業計時存儲過程處理預定作業小結作者簡介資料交換中心的方案設計 2007年5月31日
2007年6月11日

關于團隊開發的一點點想法 最近在幹活中終于體會到了一點點團隊開發的思想。但是我覺得我們的團隊開發做的還不是很好,是以我想在這裡談一點點這些日子的感受,讓自己也能記得清楚一些,在以後的工作中也能改正彌補一下現在的不足。

團隊開發真的是一件很不容易的事情,而做大的項目,必須要由團隊來完成,在這過程當中,會出現很多很多的問題,因為開發人員都是人,不可能像機器執行程式一樣,隻要有固定的代碼,就不會出現代碼以外的問題,更何況不是一個人而是一群人。是以如果想讓一群人按照既定的規則來進行各自的活動的話,就要有一套合理的規則和方法,這些方法就是軟體工程,但是那些大條大框我就不說了,我現在還沒有特别多的體會,我隻結合軟體工程說一說我現在的小體會。

首先我要強調文檔的重要性,從開發過程來講,應該是首先有三個文檔-需求文檔、設計文檔、資料庫設計說明文檔,然後把設計文檔的内容意義傳達給每個開發人員,所有開發人員都要對文檔進行評審,評審的過程也是思想接近的過程,設計思路的傳遞也就在這兒。等到整體架構設計完畢,就需要分頭來進行詳細設計了,這時還有個關鍵點就是做架構設計的人員要把每個子產品要完成的功能和接口明确給每個人,這樣做出來的各個子產品才能很好的配合在一起。詳細設計的時候每個子產品要完成的功能都要詳細到每個方法,特别是公有方法,要對每個參數和傳回值做出詳細的說明,這樣在後期的調用時就會有據可依了。

在一切設計及評審都結束後就可以開始整體編碼了,我覺得這時候編碼的效果是最好的。因為在詳細設計之前編碼,有很多時候會因為設計不充分而導緻後期改了又改,相信程式員是最反感改程式的,特别是改别人的程式,更令人難以忍受的是改那些沒有良好結構也沒有設計文檔的程式。是以在完成設計之前最好不要開始大批量的寫程式,如果寫,也要有相應的文檔。

還有就是對于一些中間産品的文檔,也要盡量詳細的寫出來,因為中間産品是子產品之間互相調用的東西,是以如果不寫出詳細的文檔就容易使兩個子產品之間的調用出現問題。

再有就是編碼規範的問題了,這個問題其實也是比較好解決的,但是不好解決的一點在于,每個人可能都有自己的編碼規範,但是如何做到一個團隊有一個統一的編碼規範就不是很容易了。

再想就是談談新人的問題,如果一個團隊中有新人加入,那麼先不用急着讓他來為公司賺錢,應該做的首先是讓他融入公司的環境,更重要的是讓他做一個團隊中符合統一規範的人,等到他完全融合進來了就可以為團隊發揮更大的有效力量了。

此上隻是一點點小小的想法,團隊合作,說着容易,其實做起來也是可以做得很好的。 posted @ 2007-06-11 11:14 wangyan 閱讀(7) | 評論 (0) |  編輯  收藏   [轉]五小時Symbian開發入門

Symbian是以Nokai為首的各手機廠商合夥開發的一個作業系統,主要用于高端的智能手機。其開發語言為C++,可以使用Microsoft Visual C++ 6.0作為內建化的開發環境,看來雖然Symbian的目标是跟微軟的SmartPhone較勁,在采取的手段和方法上卻也是不拘一格,微軟更是暗暗叫苦,誰讓當時vc6設計的這麼開放,結果被敵人拿去做武器了。

本文主要針對的是Symbian開發入門,是以應該是非常簡單的事,因為畢竟Symbian的開發語言是C++,并不會因為是用于手機的作業系統就複雜了多少,就象很多人一直挂在嘴邊的J2ME也畢竟是Java語言,并不會因為用在手機上就高深了多少一樣。5小時是我從對Symbian一無所知到完成本文花在Symbian上的所有時間。

因為是用于手機的作業系統,是以我們研究Symbian的話,先標明一款手機再說。Nokia的60系列平台是一個很不錯的選擇,Nokia根據手機的螢幕大小和價格高低把手機分成了多個系列,60系列目前有兩款手機:7650和3650。60系列采用Symbian os 6.1,然後又根據手機螢幕的特點對UI做了一些修改,這個被修改了的Symbian就被稱為Nokia的60系列平台。

是以入門的第一步就是要下載下傳S60的SDK,可以從Nokia的開發論壇上下載下傳:http://www.asia.forum.nokia.com/chinese/sch/main/series60.html。看Nokia網站上最新的是1.0,不過下面又有個0.9中文版,是以自然要下載下傳這個0.9版了。100多兆吧,不想下的話,可以跟Nokia要CD光牒,估計他們應該很高興給。這個0.9中文版的模拟器是中文版的,而且有支援GBK和UNICODE轉換的類,不知道1.0的英文版有沒有。

下載下傳完了就是安裝,選一個目錄裝就是了,不過最好裝在C槽上。可能是考慮到Windows平台和Unix平台都能用的緣故,這套SDK在處理盤符和目錄時比較弱智,我當時SDK裝到C槽,自己的程式放到D盤用vc6生成新項目就有問題,經觀察是盤符的問題。是以保險起見的話,最好裝在C槽,有興趣的可以替Nokia測試一下。另外,還需要Java的運作庫和Perl,SDK裡也都帶了,不過他自帶的Perl在我的XP下裝有問題,我下載下傳了一個最新的ActivePerl才最終算是安裝完畢。從SDK的安裝來看,這幫搞手機的搞軟體好像确實不太專業。

剛才說了,我的Symbian安裝到了C槽,在C槽的Symbian目錄下,有一個6.1的目錄,6.1目錄下有兩個目錄:Series60和Shared。還好,從名字上能看出大體的意思。請一定注意Series60目錄下的Epoc32/BUILD目錄,因為這個目錄以後要反複的用到。

接下來的任務就是要編譯一下HelloWorld,然後再運作一下看看了。首先得确認你的系統裝VC6了(最好能裝sp3以上,否則将來用到vc6時會報警),而且得把C:/Program Files/Microsoft Visual Studio/VC98/Bin

放到你的PATH裡,主要是用nmake.exe。是以如果你有nmake的話,不裝vc6也可以看helloworld。

找到helloword例子的目錄,在我這裡是C:/Symbian/6.1/Series60/Series60Ex/HelloWorld/group

Symbian裡,一個Project通常是按inc,src,group等目錄組織,group目錄裡通常放的是項目檔案,是以編譯時要先到這裡。用指令提示符模式進入剛才說的那個目錄下,然後執行bldmake bldfiles

這個指令會在group目錄下生成一個abld.bat的批處理檔案,并且會在C:/Symbian/6.1/Series60/Epoc32/BUILD下生成C:/Symbian/6.1/Series60/Epoc32/BUILD/SYMBIAN/6.1/SERIES60/SERIES60EX/HELLOWORLD/GROUP這個深的一個目錄,并在最底層目錄下生成一堆.make檔案。(實在了解不了為什麼要這麼搞?因為他們是生産手機的?)

雖然它生成了這麼多東西,但是我們不要管,繼續輸入abld build wins udeb

這個指令會編譯我們的程式,最後在C:/Symbian/6.1/Series60/Epoc32/Release/wins/UDEB

目錄下生成我們的helloworld,然後我們可以從開始菜單裡運作模拟器的debug版,打開other目錄就可以運作helloworld了。

如果要在VC6裡編譯和運作HelloWorld,在運作完bldmake bldfiles後,運作abld makefile vc6,則會生成vc6的dsw檔案,位置在C:/Symbian/6.1/Series60/Epoc32/BUILD/SYMBIAN/6.1/SERIES60 /SERIES60EX/HELLOWORLD/GROUP/HELLOWORLD/WINS

看Symbian把這點事搞得這麼麻煩,也真是不容易。

如果要直接在vc6裡建立新項目的話,要把C:/Symbian/6.1/Series60/Series60Tools

目錄下的檔案拷貝到vc6的模闆目錄下才可以。

折騰到這裡,可能得花2個多小時吧,剩下的兩個多小時得看看文檔了。

先看看HelloWorld的幫助文檔,了解一下Symbian程式的體系結構。Symbian程式也是按照VC的文檔視圖結構來組織程式的,有Application類CAknApplication,有Document類CAknDocument,有Frame類CAknAppUi,有視圖類CCoeControl等,跟vc的結構好像是差不多的,但感覺上它的Document類好像是做樣子的,我還沒看到這一塊。關于這些類之間的調用關系,在HelloWorld的文檔裡有個順序圖非常好,一看便知。

在看Symbian的代碼時,感覺最不适應的可能就是經常看到PushL和Pop函數,還有就是很多的函數都有L或LC的字尾。其實這是Symbian的例外處理機制。比如說我們定義了一個指針,給它配置設定了空間,可是在使用它的時候程式突然間出現了緻命錯誤中止了,那這個指針占用的位址空間我們肯定是收不回來了,在PC上程式設計這一點可能問題不大,記憶體那麼多,而且用不了多長時間就重新開機動了,但是Symbian的設計者可能認為這在手機上是不行的,是以對這一點做了很多的設計。Symbian有一個Clean up stack,在使用指針時,用PushL把指針壓入棧中,使用完後在用Pop彈出棧,如果在中間調用可能導緻崩潰的函數時果真出現了問題,那麼Clean up stack可以通過調用該指針的析構函數回收占用的空間。這些可能導緻崩潰的函數在Symbian裡被稱為可能Leave的函數,是以就在這些函數的尾部加了一個L。而加LC字尾的函數表明該函數已經在内部把指針用PushL壓入clean up stack了,調用時無需再用PushL,直接調用完用Pop既可。Clean up stack還提供了一個PopAndDestroy函數,就是彈出棧後再銷毀指針。順便提一句,正式因為有了Clean up stack機制,是以Symbian在有些地方看起來跟VC的程式不太一樣,比如說很多類的構造函數都不用,用NewL或NewLC構造,配置設定位址時的操作符new()也變成了new(ELeave)。上述内容可以看一下Symbian程式設計基礎中的記憶體管理一節。

Symbian自己定義了一堆的資料類型,如果不想找麻煩的話,還是乖乖的用這些類型的好。簡單說一下,整型有TInt和TUint,其中又分為8位的,16位的和32位的,如TInt8,TInt16,TInt32;文本類型是TText,又細分為TText8和TText16,但内部都是Unicode的,是以實際上内部引用應該都是TText16;bool型是TBool,對應的值有ETrue和EFalse;浮點型是TReal,但又分為TReal32和TReal64;還有一個引用類型TRefByvalue<T>,是以模闆類的形式提供的。

因為Symbian是沖着更面向對象設計的,是以在我們常見的字元串這塊變化比較大,在Symbian裡叫descriptor。最底層的是兩個抽象類TDesC和TDes,實際上TDes也是繼承的TDesC,TDesC中的C字母是常量constant的意思。即帶C字母結束的都是定義的常量,是不可以修改的,而不帶C的都有一個最大長度的限制,是可以修改的,下面也是同樣的道理。指針描述符是TPtrC和TPtr,類似于C++中的char *;緩沖區描述符(Buffer descriptor)是TBufC和TBuf,類似于char [];堆描述符是HBufC,類似于(char *)malloc(length+1)的用法。具體用時,上述的類型又分為8位的和16位的。舉個例子:

TBuf<64> buf;

CEikonEnv::Static()->ReadResource( buf, R_EXAMPLE_VIEW_TITLE );

先定義了一個最大長度是64的緩沖區,然後讀入名為R_EXAMPLE_VIEW_TITLE的資源。

再例如:

TText8 *str = (TText8*)"示範視窗标題";

TPtrC8 source( str );

iInfoText = HBufC::NewL( source.Length() );

TPtr16 ptr = iInfoText->Des();

定義一個8位的字元串str,然後構造一個指針常量source,根據source長度再定義一個16位的指針,下一步我這裡沒寫,但明顯着應該是把gbk的轉換為unicode了。

Symbian的資源檔案一般是以rss為擴充名的,沒有專門的資源檔案編輯器,使用者必須用記事本打開rss檔案手工編寫rss檔案。這個都有一定的規則和方法,參考例子不難編寫自己的資源檔案。需要注意的一點是,如果資源檔案裡包含中文,那麼必須把檔案另存為utf-8格式的才可。

入門相對來說是比較簡單的,但精通就需要大量的實踐了。

作者簡介

侯月文:2000年在聯想軟體做Linux軟體開發,2001年年底去四維時代工作,從事移動裝置相關開發工作。

posted @ 2007-06-11 09:52 wangyan 閱讀(15) | 評論 (0) |  編輯  收藏  

.net開發過程中,錯誤集錦 2007年7月10日 System.Data.OracleClient 需要 Oracle 用戶端軟體 8.1.7 或更高版本 2007年6月25日 2007年6月11日 2007年6月8日 2007年6月6日 應用程式結構 向應用程式中添加預定作業生成Web服務生成Windows服務擴充流程層以處理預定作業作業計時資訊檢索和設定作業計時資訊調用作業計時存儲過程處理預定作業小結作者簡介資料交換中心的方案設計 2007年5月31日
2007年6月8日

[轉]對web.config進行新增修改删除讀取操作      摘要: 1.建立一個class,ReadWriteConfig.cs using System;using System.Configuration;using System.Reflection;using System.Web;using System.Xml;public enum ConfigFileType{ &n...   閱讀全文 posted @ 2007-06-08 14:37 wangyan 閱讀(13) | 評論 (0) |  編輯  收藏  

.net開發過程中,錯誤集錦 2007年7月10日 System.Data.OracleClient 需要 Oracle 用戶端軟體 8.1.7 或更高版本 2007年6月25日 2007年6月11日 2007年6月8日 2007年6月6日 應用程式結構 向應用程式中添加預定作業生成Web服務生成Windows服務擴充流程層以處理預定作業作業計時資訊檢索和設定作業計時資訊調用作業計時存儲過程處理預定作業小結作者簡介資料交換中心的方案設計 2007年5月31日
2007年6月6日

[轉]整合Web和Windows服務——按預定時間間隔運作ASP.NET代碼

作者:Andrew Needleman

相關技術:C#、.NET、ASP.NET、Window

難度:★★★★☆

讀者類型:資料庫開發人員、系統結構設計人員

    [摘要]本文讨論了如何安排ASP.NET代碼的運作和N層體系結構設計,介紹了Web服務和Windows服務基礎知識。

    由于Web服務可以與ASP.NET應用程式的其餘部分在相同的應用程式上下文中運作,是以它可以在現有代碼所預期的相同上下文中執行。因為Windows服務可以在Windows啟動時自行啟動,是以我将通過Windows服務來啟動Web服務調用。

    假設您已經用ASP.NET編寫了一個出色的N層應用程式,并且想要擴充它以執行預定任務。例如,每兩個小時向資料庫中的標明使用者發送電子郵件,或者定期分析ASP.NET緩存中的資料以進行應用程式運作狀況的監視。您不希望從ASP.NET應用程式中丢棄您的對象模型或者在單獨的計劃程式和ASP.NET應用程式之間建立太多的依賴項,那麼您如何在避免這一點的同時仍然能夠讓這些應用程式一起工作呢?在基于.NET Framework的應用程式中,經常使用計時器按照預定時間間隔執行活動,是以使用一個計時器似乎是适當的解決方案。您可以從Global.asax中的 Application_Start處理程式中啟動計時器以運作預定任務。遺憾的是,該解決方案在應用程式域、程序或系統重新啟動方面還不夠健壯,這是因為必須向應用程式送出請求以啟動計時器。ASP.NET是一種隻響應HTTP請求的被動程式設計範型,是以程序或使用者輸入必須調用代碼以便它能夠運作。

    更好的解決方案是使用Web服務(Web Service)提供ASP.NET應用程式的接口,并且生成按照預定時間間隔調用它的Windows服務。這樣,ASP.NET應用程式就不必擁有日程安排邏輯,并且隻需要關心執行那些它已經能夠執行的任務。由于Web服務可以與ASP.NET應用程式的其餘部分在相同的應用程式上下文中運作,是以它可以在現有代碼所預期的相同上下文中執行。因為Windows服務可以在Windows啟動時自行啟動,是以我将通過Windows服務來啟動Web服務調用。是以,即使伺服器重新啟動,應用程式也能夠啟動自身。這一重新啟動功能使Windows服務成為對該任務而言比典型的基于Windows的應用程式更為健壯的解決方案。這也是為什麼Windows服務能用于很多背景程序(例如IIS)的原因。

    本文,我将示範如何做到這一點,同時在日程安排應用程式和ASP.NET應用程式之間建立最少數量的依賴項。該解決方案涉及到對啟動ASP.NET作業的日程安排應用程式進行簡化。在日程安排應用程式中,除了它調用的Web服務終結點以外,将不會調用特定于ASP.NET應用程式的邏輯。Windows服務将使用app.config檔案來存儲Web服務的UR 以及Windows服務在對Web服務進行的調用之間應當等待的時間間隔。通過在Windows服務的app.config檔案中存儲這兩個設定,您可以更改它們,而無須重新編譯Windows服務。如果您需要在應用程式調用時更改它的行為,則可以隻更改ASP.NET應用程式中的邏輯;但是,您不必更改日程安排應用程式的代碼。這意味着日程安排應用程式将與ASP.NET應用程式中的更改隔離。

    注意:該解決方案所基于的前提是——有一些任務隻應當在正在運作的ASP.NET應用程式的上下文中執行。如果這不是您任務的要求,則您應當認真考慮直接從 Windows服務中引用ASP.NET應用程式的業務邏輯程式集,并且繞過ASP.NET程序以激發這些任務。

應用程式結構

.net開發過程中,錯誤集錦 2007年7月10日 System.Data.OracleClient 需要 Oracle 用戶端軟體 8.1.7 或更高版本 2007年6月25日 2007年6月11日 2007年6月8日 2007年6月6日 應用程式結構 向應用程式中添加預定作業生成Web服務生成Windows服務擴充流程層以處理預定作業作業計時資訊檢索和設定作業計時資訊調用作業計時存儲過程處理預定作業小結作者簡介資料交換中心的方案設計 2007年5月31日

圖1 計劃

    典型的ASP.NET應用程式是用一系列執行特定功能的獨立層生成的。在我的特定示例中,我具有資料庫通路類、業務邏輯類、業務流程類以及作為這些層的入口點的ASP.NET頁(參見圖 1)。

    ASP.NET頁隻用來顯示和檢索資料,它們是實際協調所有工作的業務流程類的接口。流程類按照正确的順序調用業務邏輯類,以便完成特定的事務,例如訂購小部件。例如,流程類可以首先調用業務邏輯以檢查庫存,然後訂購小部件,并且最終将庫存減少至适當的水準。

    業務邏輯類決定如何調用資料庫通路類,并且根據需要處理該結果,以獲得可以用于其他操作的最終結果。例如,業務邏輯可以用來計算包括特定州的稅款在内的總價格。首先,您可能需要使用資料通路類從資料庫中檢索該州的稅率以及基本價格,然後将它們相乘以查找每個項的總稅款。資料庫通路類保持該邏輯,以便連接配接到資料庫,并且以可供更高層使用的格式(例如,DataSet、DataTable或DataReader)傳回結果集。這些類隻是從資料庫中檢索資料,并且按照回報給它們的資訊來更新該資料庫;它們不處理結果。例如,它們可能檢索特定州(美國)的稅率,但是它們不會計算訂單的總稅款。

    Microsoft Data Access Application Building Block通過提供更容易的方式與資料庫和存儲過程進行通信簡化了資料通路類。例如,您可以對它的SQLHelper對象的FillDataSet方法進行調用,以便使用一行代碼根據存儲過程的輸出來填充DataSet。通常,您必須編寫代碼來至少建立DataAdapter和一個指令對象,而這至少需要四行代碼。Data Access Application Block連接配接到資料庫中的存儲過程。該存儲過程提供通路和修改資料庫中的資料所需要的SQL代碼。

向應用程式中添加預定作業

    ASP.NET Web服務能夠提供保持任務邏輯的現有ASP.NET應用程式的接口,該接口充當該服務和調用ASP.NET應用程式以采取操作的Windows服務之間的中間人。Windows服務随後将按照預定時間間隔調用ASP.NET應用程式。

.net開發過程中,錯誤集錦 2007年7月10日 System.Data.OracleClient 需要 Oracle 用戶端軟體 8.1.7 或更高版本 2007年6月25日 2007年6月11日 2007年6月8日 2007年6月6日 應用程式結構 向應用程式中添加預定作業生成Web服務生成Windows服務擴充流程層以處理預定作業作業計時資訊檢索和設定作業計時資訊調用作業計時存儲過程處理預定作業小結作者簡介資料交換中心的方案設計 2007年5月31日

圖2 運作預定作業

    ASP.NET Web服務能夠向您提供保持任務邏輯的現有ASP.NET應用程式的接口。該接口充當該服務和調用ASP.NET應用程式以采取操作的Windows服務之間的中間人。Windows服務随後将按照預定時間間隔調用ASP.NET應用程式。通過在現有ASP.NET應用程式中生成ASP.NET Web服務,可以在預定作業中重新使用已經為該ASP.NET應用程式建立的業務對象和邏輯。圖2顯示應用程式流程的詳細資訊——從用戶端Windows服務應用程式到在該伺服器上運作的Web服務啟動,始終貫穿于每個預定任務的執行。

.net開發過程中,錯誤集錦 2007年7月10日 System.Data.OracleClient 需要 Oracle 用戶端軟體 8.1.7 或更高版本 2007年6月25日 2007年6月11日 2007年6月8日 2007年6月6日 應用程式結構 向應用程式中添加預定作業生成Web服務生成Windows服務擴充流程層以處理預定作業作業計時資訊檢索和設定作業計時資訊調用作業計時存儲過程處理預定作業小結作者簡介資料交換中心的方案設計 2007年5月31日

圖3 應用程式附加功能

    正如您可以在圖3中看到的那樣,該過程要求對前面描述的标準分層進行一些修改。Windows服務将按照指定的時間間隔喚醒ASP.NET Web服務。然後,ASP.NET Web服務将調用Web應用程式流程層中的方法,以實際确定應當運作哪些預定作業,并随後運作它們。在實作了基本解決方案以後,您可以使用用戶端app.config檔案來确定Windows服務調用Web服務的時間間隔。接下來,您可以添加業務流程層所需要的功能,以便周遊和運作作業。許多N層專家對于流程層的興趣肯定超過了對其餘層的興趣,是以我将最後讨論資料庫表、資料庫存儲過程、資料通路代碼和業務邏輯。最後,從底部(資料庫表級别)到中部(業務邏輯層)向應用程式的現有層中添加代碼,以便支援流程層所使用的作業功能。

生成Web服務

    要生成Web服務,請首先向與現有ASP.NET代碼位于相同層中的ASP.NET應用程式中添加JobRun ASP.NET Web服務。確定您的ASP.NET項目具有對業務邏輯、流程和資料通路項目的引用。接下來,要在JobRun Web服務中建立RunJob Web服務方法,Web服務方法将需要調用流程層的相應函數以運作适當的作業。這意味着RunJob方法可以像下面一樣簡單:

[WebMethod]

public void RunJob()

{

    Flow.JobFlow jf = new Flow.JobFlow();

    jf.RunAllActiveJobs();

}

    使用RunJob函數建立JobFlow類(它位于流程層中)的執行個體并調用它的RunAllActiveJobs函數。JobFlow函數的RunAllActiveJobs完成了協調作業運作的所有實際工作,而RunJob函數隻是充當該序列的入口點。請注意,這段代碼無法防止作業同時在一個以上的線程中運作——如果Windows服務過于頻繁地安排任務(速度超過了任務的運作速度),或者如果其他某個應用程式調用了入口點,則可能發生這種情況。如果該方法不是線程安全的并且允許多個線程同時調用它,則可能給這些作業的結果帶來問題。例如,如果作業X向Mary Smith發送了一封電子郵件,但是在作業Y查詢資料庫以處理其電子郵件時尚未更新資料庫,則Mary可能收到兩封電子郵件。為了同步對該函數的通路,我将使用System.Threading命名空間中的Mutex類:

private static Mutex mut = new Mutex(false, "JobSchedulerMutex");

    Mutex支援跨程序同步,是以這可以防止多個程序同時運作——即使涉及到兩個不同的ASP.NET輔助程序。現在,讓我們更改RunJob方法以使用Mutex,進而確定在啟動作業之前沒有其他作業運作。

代碼段1 RunJob Web Service:

[WebMethod]

public bool RunJob()

{

    bool ranJob = false;

    mut.WaitOne();

    try

    {

        Flow.JobFlow jf = new Flow.JobFlow();

        jf.RunAllActiveJobs();

        ranJob = true;

    }

    finally

    {

        mut.ReleaseMutex();

    }

    return ranJob;

}

    正如您可以在代碼段1中的RunJob函數中看到的那樣,可以調用Mutex的WaitOne函數以使該線程等待,直到它在執行之前成為唯一的線程。然後,調用ReleaseMutex函數以訓示您已經執行完隻需要在一個線程中運作的代碼。當然,在這裡阻塞可能不是正确的解決方案。您可以選擇在另一個線程已經執行作業時(在此情況下,您可以為WaitOne方法指定短暫的逾時)立即傳回,并且在無法獲得互斥鎖時立即從RunJob中傳回。将該函數的所有主要操作都放到一個try-finally塊中,以便即使RunAllActiveJobs函數中的意外異常導緻RunJob函數退出,也會調用ReleaseMutex。

    您可能希望使用某種形式的身份驗證和授權(可能使用Windows安全)來保證 Web服務的安全,以確定必須經過正确的授權才能運作該服務,但是我不打算在本文對此進行詳細讨論。

    既然您已經生成了Web服務以便可以從另一個應用程式中調用它,那麼現在就讓我們生成能夠使用它的Windows服務。

生成Windows服務

    首先, 在Visual Studio .NET的另一個執行個體中建立一個新的Windows服務項目,然後将其命名為InvokingASPNetService.cs。通過按以下方式添加Main方法來確定該服務将正确啟動:

public static void Main()

{

    ServiceBase.Run(new InvokingASPNetService());

}

    現在,為下列命名空間添加using語句:

using System.Configuration;

using System.Globalization;

    通過右鍵單擊InvokingASPNetService.cs的設計表面并選擇“Add Installer”,添加該服務的安裝程式。您應當将所建立的serviceInstaller1 的StartType屬性更改為Automatic,以便Windows服務在Windows啟動時啟動。将serviceInstaller1 的 ServiceName 屬性設定為InvokingASPNetService,以便在服務管理器中适當地命名它,然後将serviceProcessInstaller1 Account 屬性更改為Local Service。

    第三步,建立對InvokingASPNetService Web服務的Web引用,然後将其命名為JobRunWebService。将JobRunWebService URL Behavior屬性更改為Dynamic,以便讓Visual Studio .NET自動用Web引用的URL來擴充app.config。所生成的代理類将在該配置檔案中查找Web服務的URL,進而使您無須重新編譯即可将 Windows服務引導至不同的終結點。

    第四,在Windows服務中建立一個方法,以便在Web服務每次被調用時運作它。該方法如下所示:

private void RunCommands()

{

    JobRunWebService.JobRunInterval objJob =

        new JobRunWebService.JobRunInterval();

    objJob.RunJob();

}

    如您所見,您将聲明Web服務代理,并且就像建立其他任何.NET對象一樣建立它。然後,調用Web服務的RunJob方法,以便在遠端Web伺服器上運作作業。請注意,每個步驟都與使用本地類沒有什麼不同,即使您使用的是Web服務。

    第五,您需要在Windows服務中調用RunCommands函數。您應當基于您希望在遠端伺服器上運作作業的頻率,按照固定的時間間隔調用該方法。使用System.Timers.Timer對象來確定RunCommands函數按照正确的時間間隔運作。Timer的Elapsed事件将使您可以在每個時間間隔流逝之後觸發您指定的任何函數(請注意,時間間隔長度是在Interval屬性中指定的)。您将使用被觸發的函數來調用RunCommands函數,以便可以自動執行該功能。預設情況下,該timer類隻在它首次到期時才會觸發事件,是以您需要通過将它的AutoReset屬性設定為true來確定它每次都反複地重置它本身。您應當在服務級别對其進行聲明,以便該服務的任何函數都可以引用它:

private Timer timer;

    接下來,建立相應的函數以初始化timer并設定它的所有相關值:

private void InitializeTimer()

{

    if (timer == null)

    {

        timer = new Timer();

        timer.AutoReset = true;

        timer.Interval = 60000 * Convert.ToDouble(

            ConfigurationSettings.AppSettings["IntervalMinutes"]);

        timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);

    }

}

    為了能夠在不重新編譯應用程式的情況下更改配置時間間隔,我已經在app.config檔案中存儲了該時間間隔,以便InitializeTimer方法可以使用ConfigurationSettings.AppSettings通路它而不是對其進行寫死,如下所示:

<add key="IntervalMinutes" value="5" />

    確定timer在計時器到期時調用timer_Elapsed函數以處理Elapsed事件。timer_Elapsed方法非常簡單,它調用剛剛生成的RunCommands函數,如下所示:

private void timer_Elapsed(object source,System.Timers.ElapsedEventArgs e)

{

    RunCommands();

}

    最後,您必須使用installutil指令安裝Windows服務。最容易的方式是打開Visual Studio .NET指令提示視窗,導航到該服務的目錄,然後運作installutil實用工具,并且指定您的程式集作為參數。

擴充流程層以處理預定作業

    一項重要的工作是擴充流程層以處理正在運作的預定作業的需要(假定作業之間的差異足夠大,以至于需要對它們進行編碼而不僅僅是參數化)。這涉及到從資料庫中的下一個啟動時間已經過去的資料庫收集所有作業,并單獨地運作它們。在流程層内部,您将建立一個名為Job的基類以提供作業所共有的全部功能。這包括一個用于初始化和檢索JobID的機制、一個用于運作作業以及在成功運作之後設定資料庫中的下一個運作的公共方法(RunSingleJob),以及一個要針對每個作業進行自定義的可重寫方法(PerformRunJob)。

    流程層還将需要為它執行的每個作業生成特定于作業的類。這些類将從基礎的Job類繼承,并将重寫Job類的PerformRunJob函數以自定義該特定作業的執行。您還會需要一個工廠類(JobFactory)以建立和初始化正确的Job類的JobID。靜态的CreateJob函數将根據傳遞到該函數中的JobID來建立适當的作業。最後,流程層将必須能夠确定需要運作的作業、周遊它們并運作它們。這就是JobFlow類将通過它的RunAllActiveJobs方法提供的功能。

    首先,讓我們在流程層項目中建立Job基類(該類将成為每個作業類的父類)。代碼段2顯示Job抽象基類的核心。它允許對其JobID進行初始化和檢索,并且能夠確定在作業成功運作後更新資料庫。JobID在建立之後,它将不會針對給定的作業進行更改,是以您必須確定在初始化之後設定函數不會更改該值。建立各個Job類的JobFactory類将設定自己的JobID值。

代碼段2 Job抽象基類:

protected bool isInitialized = false;

protected int mJobID;

public int JobID

{

    get { return mJobID; }

    set

    {

        if (!isInitialized)

        {

            mJobID = value;

            isInitialized = true;

        }

        else throw new InvalidOperationException("JobID already set.");

    }

}

public void RunSingleJob()

{

    if (isInitialized)

    {

        PerformRunJob();

        RecordJobSuccess();

    }

}

protected abstract void PerformRunJob();

protected void RecordJobSuccess()

{

    JobLogic jl = new JobLogic();

    jl.UpdateJobDone(JobID);

}

    RunSingleJob函數确定該作業的JobID已經初始化,運作作業(PerformRunJob),并且在成功運作之後用RecordJobSuccess方法更新資料庫。isInitialized變量用來確定每個作業在運作之前都使它的JobID得到初始化。PerformRunJob抽象方法由派生的Job類實作,并且保持任務的實際邏輯。在作業的實作(PerformRunJob方法)成功運作之後,基類調用 RecordJobSuccess函數,該函數使用業務邏輯層的JobLogic類的UpdateJobDone方法來記錄它在資料庫中運作的時間以及預定的下一個運作時間。稍後,我将建立業務邏輯層的JobLogic類。

    Job類既提供初始化JobID變量的功能,又提供在成功時用下一個運作時間更新資料庫的功能。另外,您隻須用特定于類的代碼重寫一個函數。這使您可以建立Job類的子類。為此,您需要建立兩個類,以便運作特定類型的作業,并且從Job類繼承以獲得它們的其餘功能。建立一個JobRunTest類和一個JobEmailUsers類,并且確定每個類都從Job類繼承,如下所示:

public class JobRunTests : Job

    現在,按如下方式重寫這兩個類的PerformRunJob方法(使用JobRunTest類作為示例):

protected override void PerformRunJob()

{

    ///Do RunTest specific logic here

}

    将特定于作業的邏輯放到該方法的内部。負責運作作業并且更新資料庫中下一個運作時間的其餘代碼是從Job基類中繼承的。您的作業将組合對現有業務邏輯類的調用,以便運作複雜的過程。既然已經有了示例作業,那麼讓我們考察一下如何使用JobFactory對象建立這些作業。

    JobFactory類用于建立每個JobID的相應子Job類。JobFactory類在它的靜态 CreateJob函數中采用JobID變量,并且傳回适當的Job子類。代碼段3顯示JobFactory中的代碼。

代碼段3 JobFactory類:

public static Job CreateJob(int currentJobID)

{

    Job myJob;

    switch(currentJobID)

    {

        case 1:

            myJob = new JobEmailUsers();

            break;

        case 2:

            myJob = new JobRunTest();

            break;

        default:

            return null;

    }

    myJob.JobID = currentJobID;

    return myJob;

}

    CreateJob函數采用目前JobID,并且在一個case語句中用它來确定應當傳回Job類的哪個子類。然後,初始化目前的JobID并且傳回從Job派生的類。既然您具有了Job基類、它的特定于作業的子類以及用來選擇要建立的類的方式,那麼您就可以考察如何使用JobFlow類将這一切組合在一起。

    要建立一個名為JobFlow的類以便收集和執行适當的作業,請添加一個名為“RunAllActiveJobs”的函數以周遊您需要運作的每個作業,并調用它們各自的RunSingleJob函數。您将需要使用RunAllActiveJobs函數來擷取預定從資料庫中經過業務層、資料通路層和存儲過程運作的作業的清單,然後使用其各自的RunSingleJob函數來運作它們。以下代碼顯示JobFlow類的RunAllActiveJobs方法如何完成這些目标:

JobLogic jl = new JobLogic();

DataSet jobsActiveData = jl.GetAllActiveJobs();

foreach (DataRow jobsActive in jobsActiveData.Tables[0].Rows)

{

    int currentJobID = Convert.ToInt32(jobsActive["JobID"]);

    Job myJob = JobFactory.CreateJob(currentJobID);

    myJob.RunSingleJob();

}

    基本上,您将在資料庫中存儲作業,同時存儲有關它們上次運作的時間以及代碼在連續兩次運作之間應當等待的時間間隔的資訊。然後,通過BusinessLogic層中帶有GetAllActiveJobs方法的JobLogic類來檢索需要運作的作業。每個活動作業的ID都用于獲得Job對象,如前所述,該對象的RunSingleJob方法可以用來執行任務。

作業計時資訊

    确定應當運作哪些預定作業意味着您需要存儲有關它們的基本資訊,例如,連續兩次運作之間的時間間隔、它們的上次運作時間和它們下一次應當運作的時間。為了完成該工作,請在SQL Server資料庫中建立一個作業表(參見表1)。

表1 Job表

Column Datatype
JobID int identity
JobTitle varchar(500)
JobInterval datetime
DateLastJobRan datetime
DateNextJobStart datetime

    JobID列保持該作業表中每個作業的唯一辨別符。JobTitle列包含作業名稱,以便您可以确定哪個作業正在運作。JobInterval列保持連續兩個作業之間的時間間隔。它們是大于1/1/1900的日期和時間間隔,在作業成功後,應當将其添加到目前時間中,以計算下一個作業應當運作的時間。例如,JobInterval字段中的值1/2/1901 意味着需要将一年和一天添加到該作業上次運作的時間中。

    DateLastJobRan列包含作業上次運作的日期和時間的datetime值。最後一列 DateNextJobStart包含作業下一次應當運作的時間。盡管該列應當是一個由JobInterval加DateLastJobRan計算結果而得的列,但如果您将該列設定為正常的datetime列,則可更生動地了解應用程式層。

檢索和設定作業計時資訊

    要通過SQL Server資料庫中新的存儲過程檢索和設定作業計時資訊,這些存儲過程必須找到該資料庫所有需要由該應用程式運作的作業,更新該資料庫中單個作業的資訊以訓示它已經運作,并且設定該作業的下一個作業運作日期。每個作業都在該資料庫中具有一個DateNextJobStart列,以訓示該作業應當運作的日期和時間。如果目前日期和時間已經超過DateNextJobStart列的日期和時間,則應當在該程序中運作該作業。選擇應該運作的作業的存儲過程如下所示:

Create PROCEDURE

dbo.Job_SelectJobs_NextJobStartBefore

@DateNextJobRunStartBefore datetime

AS

Select * FROM JOB Where DateNextJobStart < @DateNextJobRunStartBefore

    該存儲過程在Job表中選擇的作業符合以下條件,其DateNextJobStart值早于(小于)@DateNextJobRunStartBefore DateTime參數的值。要查明應當運作哪些作業,隻須通過該存儲過程的參數傳入目前日期和時間。既然您可以選擇需要運作的作業,那麼您就可以轉而生成該過程以便在作業運作之後更新它們。用單個作業的上一個運作日期和下一個運作日期更新資料庫的存儲過程如下所示:

Create PROCEDURE dbo.Job_Update_StartEnd_CalcNext

@JobID int,

@DateLastJobRan datetime

AS

Update JOB

SET

DateLastJobRan = @DateLastJobRan,

DateNextJobStart = @DateLastJobRan + JobInterval

Where

JobID = @JobID

    該過程用一個新的DateLastJobRan來更新由@JobID辨別的作業,并且通過将JobInterval與傳入的@DateLastJobRan相加來計算DateNextJobStart值。該過程隻應當在@JobID中引用的作業之後運作,并且應當用等于作業上次運作的日期和時間的@DateLastJobRan參數來調用。

調用作業計時存儲過程

    您可以通過添加一個名為JobAccess的新類來擴充資料通路層,以便調用作業計時存儲過程。資料通路層中函數的作用是将業務層傳遞給該層的參數轉換為存儲過程資料庫查詢,并且向業務層傳回結果。資料通路層的函數中的參數将鏡像它們所通路的存儲過程的那些參數,因為它們不對這些值執行任何業務邏輯。您将通過Microsoft Data Application Building Block的SQLHelper類通路資料庫。該類包含用于簡化資料通路代碼的功能,進而使您的代碼更為簡潔,可讀性更高。

    要更改資料通路層以運作預定作業,請首先向現有資料通路層中添加JobAccess類,以便保持安排作業所需的函數。接下來,在JobAccess類中建立一個函數,以傳回需要通過調用Job_SelectJobs_NextJobStartBefore存儲過程運作的作業的DataSet。您還将需要在JobAccess類中建立一個函數以調用Job_Update_StartEnd_CalcNext存儲過程,但不傳回結果。

    首先,将JobAccess類添加到資料通路層。然後,編輯JobAccess類以添加下列“using”語句:

using System.Data;

using System.Data.SqlClient;

using Microsoft.ApplicationBlocks.Data;

    現在,讓我們考察一下如何添加SelectJobsBeforeDate函數以檢索需要運作的作業的清單。以下為SQLHelper的ExecuteDataset函數的簽名:

public static DataSet

ExecuteDataset(

string connectionString, string spName,

params object[] parameterValues)

    以下為SelectJobsBeforeDate函數,它使用ExecuteDataset來調用Job_Update_StartEnd_CalcNext存儲過程,并且傳回結果的DataSet:

public DataSet SelectJobsBeforeDate(DateTime beforeDate)

{

    return SqlHelper.ExecuteDataset(

        ConnectionInfo.connectionString,

        "Job_SelectJobs_NextJobStartBefore, myparams);

        new object[]{new SqlParameter("BeforeDate", beforeDate)});

}

    在作業運作之後,您需要執行相應的存儲過程以更新有關作業的狀态資訊。完成該工作的方法UpdateJob将使用SQLHelper類的ExecuteNonQuery方法。以下是它的簽名:

public static int ExecuteNonQuery(

    string connectionString, string spName, params object[]

    parameterValues)

    UpdateJob方法可以按以下方式編寫:

public void UpdateJob(int JobID, DateTime dateLastJobRan)

{

    string connStr = ConnectionInfo.connectionString;

    string spName = "Job_Update_StartEnd_CalcNext";

    SqlParameter myparam1 = new SqlParameter("JobID", JobID);

    SqlParameter myparam2 = new

        SqlParameter("DateLastJobRan",dateLastJobRan);

    object[] myparams = {myparam1, myparam2};

    SqlHelper.ExecuteNonQuery(connStr, spName, myparams);

}

    JobAccess類中的UpdateJob函數應該鏡像傳遞給它所使用的存儲過程的參數。是以,UpdateJob函數具有一個JobID參數和一個dateLastJobRan參數,并且它們的資料類型與Job_Update_StartEnd_CalcNext存儲過程中的參數相同。使用JobID和dateLastJobRan參數,您可以建立兩個SqlParameters,将它們放到myparams對象數組中,并且使用ExecuteNonQuery函數來執行該存儲過程。既然您已經建立了JobAccess類,那麼您需要建立最後一個類層,以便将流程層和資料通路層連接配接起來。

處理預定作業

    最後一個必須加以修改以便處理預定作業的層是業務邏輯層,我将其稱為JobLogic。該類将對流程層和資料通路層之間的變量執行基本邏輯。

    首先,使用下列語句向DataAccess層中添加JobLogic類:

using System.Data;

using ScheduledWebService.DataAccess;

    其次,生成JobLogic類的GetAllActiveJobs函數,以查找所有仍然需要在目前時間或之前運作的作業,如下所示:

public DataSet GetAllActiveJobs()

{

    JobAccess ja = new JobAccess();

    return ja.SelectJobsBeforeDate(DateTime.Now);

}

    GetAllActiveJobs函數建立JobAccess類的執行個體,并且用目前日期的參數值調用它的SelectJobsBeforeDate。GetAllActiveJobs選取目前日期以傳遞給該函數,是以您可以查明哪些作業被安排在目前時間之前運作。

    最後,建立JobLogic類的UpdateJobDone函數以更新資料庫,以便訓示所指定的作業剛剛完成,如下所示:

public void UpdateJobDone(int JobID)

{

    JobAccess ja = new JobAccess();

    ja.UpdateJob(JobID, DateTime.Now);

}

    該函數建立JobAccess類的執行個體并且調用它的UpdateJob方法。它傳遞JobID參數,然後使用dateLastJobRan參數的目前日期。您需要将目前日期和時間傳遞給UpdateJob函數,因為它是作業成功完成的時間。

小結

    通過用自動完成的任務擴充ASP.NET應用程式,可以顯式計劃事件,而不是等待執行代碼的請求。您可以利用這一功能執行多種任務——從運作複雜的計算到定期建立報告并将其發送給經理。這樣的任務可以同時重用現有的邏輯和ASP.NET層中的對象,并且可以減少開發時間和提高可維護性。您還可以擴充該計劃程式啟動的作業,而無須更改啟動它的Windows服務。

    請注意,對于我在本文中讨論的内容,有許多不同的情況。例如,您可以不建立自定義的Windows服務來充當計劃程式,而是使用某種像Windows任務計劃程式一樣簡單的工具,它非常可靠,并且實作了本文中讨論的大多數功能,而無需建立自定義的Windows服務來充當計劃程式。總之,.NET Framework已經大大簡化了Windows服務的建立,是以即使您先前已經發現它們非常難以使用,您也應當将它們作為一種選擇而重新加以考慮。類似地,Web服務是應用程式向其他應用程式公開功能的一種很好的方式,并且将繼續在這一方面發揮作用。

作者簡介

    Andrew Needleman是Claricode的一名經營合夥人,這是一家位于波士頓附近的咨詢公司,專門從事在 .NET中設計和開發N層Web應用程式。他已經教育訓練了數以百計的C#、.NET Framework和Visual Basic .NET領域的開發人員。

posted @ 2007-06-06 11:39 wangyan 閱讀(19) | 評論 (0) |  編輯  收藏   資料交換中心的方案設計

資料交換中心的方案設計

中關村線上 【轉載】 作者: 2005年01月29日 01:41

    城市電子政務系統是構築在各個政府部門(局委辦)的資訊系統之上 ,是把各個局委辦的資料庫作為其共享的一部分。而我國政府的資訊系 統是在不同時期、由不同的公司、利用不同的工具、在不同的開發平台 開發出來的,并且運作在不同的作業系統和不同的資料庫平台之上 。這就是"資訊孤島"造成的主要原因。要建立跨各政府部門的辦公平 台,實作異構系統之間、新老系統之間的資訊的透明交換是基礎性工作 。

建立安全、穩定、高性能、跨平台、跨系統、跨應用 、跨地區的資訊交換平台是最重要的軟體平台,各行業各部門的系統将 統一通過這一平台進行資訊交換,以達到整個電子政務網内資源共享互 通的效果。

4.3.1 資訊交換的需求分析

電子政務中資訊交換按交換對象分為三大類:

基于政府外網之上的政府部門之間的資訊交換

基于政府内網之上的政府内部之間的資訊交換

基于Internet網和政府外網之上的政府同企業 、市民之間的資訊交換

例如,一個城市财政局辦理"行政事業性收費"立項的流程可描述如下 :由上圖可見,它涉及"事業機關-------政府(财政局)" ;政府部門之間,"綜合處-------付局長------局長 ";政府之間,"财政局------物價局","财政局---- -财政廳"之間的資訊交換。

一個城市的政府機關達幾十個(例如武漢市的委局辦就有139個 )甚至100多個,他門之間的資料交換呈網狀交換,如下圖所示:

很明顯,以局的資訊系統即所謂資訊孤島為機關設計同其它局交換的信 息交換,其代價、技術的複雜度是相當高的。這種內建的方式是用手工 程式設計,對每一個機關都要開發一個接口。如果有N個應用系統需要內建 ,就需要建立N(N-1)/2個接口程式。如果一個政府有100個 部門,其接口程式的開發工作量是可想而知的。如果某個機關的資訊系 統發生變化,則相應的接口都會要進行調整。

根據一項調查,世界上每年花費在應用接口上的維護費就占企業IT投 資的30%----40%。相對這種資料傳遞接口的方法 ,最近幾年,人們提出了安全總線法和擴充卡法。其概念模型描述如下 :

在總線上,點之間交換是對等的,若某個節點有故障不影響其它節點之 間的通訊。擴充卡、總線、控制器一起構成了資訊交換平台 。它集中了所有的資料交換接口,進行所有的資訊交換及其管理工作 ,有人也把它叫作政府總線(BUS)。在可信資訊總線拓撲結構中 ,連接配接的數量與要連入的應用個數相等。增加一個節點 ,增加的連接配接也隻有一個。通過總線,應用之間的維護、安全控制 、資訊過濾都變得非常容易。它不需要的遺留系統進行大的修改或重新 開發。

由于個人、企業、政府部門都是用已有的工具或系統設計表格 、填寫表格、審批表格,是以資訊的格式、描述方法 、傳遞方式都是不一樣的,常見的記錄、傳遞方式有:txt ,doc,wps,rtf,ppt,xml,htp,pdf ,rm,bmp等等。是以在這種環境下,要進行資訊交換是十分困難 的。由于總線思想、XML的出現,計算機系統之間實作統一的資訊交 換成為可能。其資訊交換可轉換成統一的格式,可描述如下:

要進行透明的資訊交換要解決一系列技術問題,資訊的格式、資訊的安全、資訊的封裝與解碼、資訊的語義的統一解釋,這就是資訊的可信交換平台的設計問題。歸納起來,在設計資料交換時,要解決以下課題:

1}資訊交換的語義識别

資料格式、文法所描述的資訊應該有效,各種系統在傳遞、讀取、解析和使用文檔中的資訊時不會産生二義性。

表達的内容、格式能滿足所有政府部門各項業務的要求 <script type="text/javascript"> </script>

2}傳輸的要求

資料格式易于傳輸,能夠實作各個應用系統之間的同步/異步資訊交換。格式技術相容各種網絡系統和通訊協定。

3)安全方面的要求

交換的資料文檔需要基于應用系統之間約定的規則進行驗證。要能建立資料格式、資料内容、網絡傳輸等不同層面的安全防護機制。

4)非功能性要求

格式穩定性高,易于管理,有良好的可擴充性和可增長性。使用該格式可降低政府部門的運作成減少人力資源。

4.3.2 資訊交換原理

1、 資訊交換模型

資訊交換是通過網絡進行的,而網絡資訊交換有國際公認的OSI (Open System Interconnect)七層模型。而電子政務資訊交換則隻注重應用層、表示層,如下圖:

在這個模型中,應用系統之間按應用層協定進行通訊,應用系統内部依靠接口提供服務。而在網絡中,為了保證應用系統能了解資訊傳輸的要求,在傳輸者、接收者之間是以XML作為媒介。

2、政務系統中的資訊交換結構

在每個交換節點上,從OSI七層網絡模型分析資料交換平台主要是解決應用層和表式層的内容。為了确定設計交換平台的功能,把表式層按功能劃分為内容管理層、資料交換層、資料傳輸層。

電子政務系中不同局之間的資料交換,由邏輯上同構的許多資料交換節點以對等的方式進行。在接口系統中定義了每個節點的标準資料交換平台的功能和邏輯表現。其意義是指:一方面,它滿足接口規範的要求,以規定的接口提供相應的功能;另一方面,在工作過程中需要與另一個結點進行互操作時,另一個結點上的标準資料交換平台也同樣是符合規範要求的,雙方在對應的協定層次上進行對話。

應用層也是OSI中的應用層。

電子政務系統中的業務應用系統都處在應用層,它們是平台的使用者,它們通過資料交換獲得資料,再加工和決策。資料交換平台把本屬各部門的異構資料聯結起來,為每個單為的應用系統提供了全局的、透明的資料交換和共享。在交換平台的支撐下,每個應用系統都可以在統一的接口的基礎之上,對政務系統中每一個部門的資料庫進行授權通路。

OSI中的表式層在次分為:内容管理、資料交換

1)、内容管理(表示層)

内容管理層是指内容的表示(存儲)、操作(傳送)和授權管理等功能。

一個标準資料交換平台的任務可以分為兩個方面,一個是對遺留業務系統(Legacy System)的資料進行整合,為交換和共享做準備;另一個是通過規範化的方式對業務系統提供統一的資料通路支援。這就要求标準資料交換平台遵從統一的資料表示方式,采用标準的XML表示資料,XML的DTD可根據業務不同而定義。

操作集合:這是資料交換功能的直接展現,應該包括查詢、擷取、送出等内容。

授權管理:它用于規定在具體的資料交換過程中,哪些業務資料能夠在多大範圍内被何種方式通路到。資料交換規範中需要給出符合實際業務需求的授權模型,并在此模型下定義相應的管理功能和授權邏輯。

内容管理層在工作過程中,如果有需要跟遠端其它資料交換結點進行互操作的時候(如擷取資料或者提供資料),通過資料交換層來完成。

在内容管理層提供簡單易用的界面友善使用者輕松定義各種類型的XML格式檔案和二進制文本格式檔案。然後該功能子產品會生成對應檔案格式的Schema(DTD)和模式檔案。此外,提供驗證機制用于檢驗所建立資料格式模型的正确性。

從功能上,這一層還可細分為以下幾個部分:

l 圖形定義及顯示子產品:構造樹形圖,為每個節點配置設定屬性用以定義資料格式的模型,另一方面通過讀入模型的XML描述檔案顯示模型的樹狀結構。

XML描述文檔及schema生成子產品:需要模組化的資料檔案主要可分為二進制檔案和XML檔案兩種類型。

XML檔案,模組化的過程實際上是産生它的schema檔案的過程。

二進制格式檔案,模組化的目的是生成這種二進制格式檔案所對應的XML格式檔案的schema,是以二進制檔案的模組化過程可分為兩個步驟,第一步将二進制的格式資訊轉化為XML描述文檔,第二步将XML描述文檔轉化為schema。

l 模型驗證子產品:對于二進制格式檔案,使用者可以在模組化後輸入實際的二進制檔案檢視對應的XML格式檔案,驗證所模組化型的正确與否。此外使用者也可以檢視生成的schema的内容。

l XSLT引擎:提供符合規範的XSLT轉換器,其它功能子產品通過調 <script type="text/javascript"> </script> 用該引擎完成XML文檔的轉換。

l 文本(二進制)檔案到XML檔案的轉換引擎:利用XML描述文檔将文本(二進制)檔案轉換為XML檔案。其它功能子產品通過調用該引擎完成文本(二進制)檔案到XML檔案的轉換。

2)、資料交換(表式層 資訊服務的支援)

資料交換層的任務是完成不同資料交換結點之間的互操作,功能上應該包括資料的定位和資料包封裝。資料的封裝和解封與操作指令一樣,是一個标準資料交換平台的規範性的重要展現。所有在節點之間傳送的資料,包括操作指令本身,都要按照規定的格式進行編排,這樣才能保證資料交換節點之間的互操作性,以屏蔽底層的實體特性的多樣性。是以要有好的資訊服務機制,必須解決以下的問題:

資訊的統一封裝,即資訊的打包和信封的書寫功能

統一編址,應支援一套統一的、簡單易用、易擴充、易管理的位址編碼體系

資訊的可靠傳輸

傳輸的效率

可管理性,要對傳輸的過程進行全程監控,提供日志、審計、會話管理、傳輸優先級設定、流量負荷分析

2) 安全的資料傳輸(表示層)

資料傳輸層用于實作資料交換結點之間的資料傳輸。在軟體層面,重要的一點就是要采用成熟的傳輸協定,譬如HTTP或SOAP。

HTTP協定具有簡單、完備、輕量級、擴充能力強等特點。較小的傳輸開銷可以保證較強的傳輸性能,完備的協定規程可以保證傳輸的穩定性。同時,通過适當的擴充,可以提高可靠性和安全性。

安全性可以通過引入基于PKI(Public Key Infrastructure,公鑰體系)的CA(Certificate Authority,認證中心)體系來解決。

4.3.3 資料交換中心的設計

要設計一個資料交換中心,實作政府部門之間的資料的透明交換。在設計中要考慮三個方面的問題:

資訊的統一表示

完整的消息服務能力

功能完備的交換平台軟體系統

1、 資訊的統一表示

要實作資訊共享,實作異構系統之間的互聯互通,資訊的統一表示是關鍵。資訊的表示應獨立于系統、平台。為了實作這一目标,在進行平台開發、應用系統開發時要制定或遵循六個方面的資訊标準:

1)、元語言标準

元語言是描述其它語言的語言。電子政務的資訊表示語言采用XML元語言标準。該标準用來對政務資訊的語言的文法、編碼、令名進行行式化描述。該标準可采用W3C制定的XML元語言标準,設計者應根據電子政務中的資訊表示的需求進行裁剪。

2)資訊編碼标準

該項标準對字元的編碼、字元集定義、字元引用、字型的表示進行了規定。一般采用W3C制訂的XML1。0為基礎,以GB13000為預設的字元集,同時也能支援GB18030字元集标準

3)中繼資料标準

中繼資料是描述電子資料的資料,制定該标準是為了友善政府資訊資源有效的儲存、查詢、再利用。在XML标準中,中繼資料的表示采用了"詞彙表"、"命名空間"、"文檔類型定義(DTD)"、XML Schema等方式實作。

在異構關系資料庫之間還可通過建立元模型、元元模型統一資料的語義。

3) 顯示标準

在電子政務系統中,要将資料和資料的顯示分開。這樣就把資料的加工同不同的輸出、顯示分開處理,而不會造成HTML中文檔結構的複雜性。顯示在不同裝置上,但内容隻有一個。顯示标準一般采用W3C推薦的層疊式樣單CSS、可擴充式樣單語言XSL。

4) 解析、轉換和封裝标準

要實時共享交換的各種資訊,必須具備效率高的資料結構封裝、解析、轉換的功能,是以必須有相應的标準。

2、完整的消息服務能力

電子政務平台是一個中間件軟體,它在資訊交換過程中要進行頻繁的資訊封裝、控制資訊的同步/異步交換、排隊處理等。是以它要有好的資訊服務機制,這就必須解決以下的問題:

資訊的統一封裝:資訊的打包和信封的書寫功能

統一編址:應支援一套統一的、簡單易用、易擴充、易管理的位址編碼體系

資訊的可靠傳輸:将資訊可靠的傳輸到目的地

路由管理:在多個資訊交換節點時,實作資訊的準确傳遞。

傳輸的效率:采用資訊的表示與交換分開、專用的交換裝置、資訊壓縮等方法提高傳輸的速度。

可管理性:要對傳輸的過程進行全程監控,提供日志、審計、會話管理、傳輸優先級設定、流量負荷分析

2、 資訊交換平台的體系結構 <script type="text/javascript"> </script>

實作資訊的交換根據環境的不同有三種方式:

1)具有相同資料庫管理系統(DBMS)的分布式系統的資料交換,可直接用

相應系統的有關功能:

在ORACLE系統中,可以利用快照技術實作表資料的交換;

在SYBASE系統中,可以利用複制伺服器 實作資料的交換;

2)利用已有的消息中間件伺服器:IBM的MQSerries、BEA MESSAGE()以及JAVA的消息服務JMS來實作。利用IBM的MQSerries進行交換可描述如下:方案采用IBM著名的Websphere、MQSeries等系列中間件産品建構基于Browser/Web Application Server/Transaction Server/Database模式的三層次/多層次應用體系結構,如圖所示把交換器配置成IBM的MQSerries。業務分為實時交換和非實時(脫機)交換處理。軟體配置分為實時交易處理和脫機交易處理兩個部分。實時處理業務通過Websphere及Txseries/CICS交易伺服器實作,非實時的業務通過MQSeries的互連,達到安全可靠地交換資料和異步交易處理的目的。

實時處理部分

實時交易處理部分中采用以WEB應用伺服器Websphere Application Server、交易伺服器Txseries/CICS等中間件為核心的多層次體系結構,以確定系統在大筆交易量情況下的可靠性和快速響應速度。

為了防止交換高峰期間對WEB應用伺服器壓力過大造成該部分處理能力的瓶頸,資料中心同時配置了多個 Websphere Application Server組成群集(Cluster)結構,共同承擔來自于前台的業務處理請求,并通過該軟體内置的CICS Client接口調用交換伺服器的遠端調用(RPC)。在各應用伺服器之前配置了WEB負載平衡伺服器,Websphere Performance Pack軟體包作為負載平衡伺服器,統一接受來自于前台的實時資料處理請求,并均勻配置設定給各WEB應用伺服器。

脫機交換處理:

對于所有脫機交易處理,在資料中心配置MQ Series Integrator和MQSeries資料傳輸中間件作為全系統的資料交換中心,承擔全系統資料交換的統一平台。運作在MQ Series基礎傳輸系統之上的MQseries Integrator作為全系統資料收發/轉發的'網關'和'郵局',專門用于負責整個網絡環境下的資料傳遞,并作為批量處理系統的前置機接收各下級機關資料交給主業務伺服器處理。

考慮到在整個系統需要和稅務、公安、衛生等系統實作資料交換,可能包含多個應用子系統,涉及各種不同的具體應用,而各個分布的子系統又需要有資料交換,需要一定程度的資料共享,是典型的松耦合結構(Loosely-coupled),在這樣一種架構下,每個子系統的資料結構都不統一,是以需要MQSeries Integrator這樣的産品,具有能簡單靈活地內建各個資料庫子系統并自動實作資料采集和分發的功能。而MQSeries Integrator正是具備這一功能的産品。

在資料交換中心除了配置MQSeries Integrator和MQ Series之外,同時配置一個資料庫專門存放整個系統中各子系統的資料格式描述,資料智能路由的規則描述,這些資訊都可以通過MQSeries Integrator提供的可視化管理工具動态修改,靈活配置。此外,各子系統均通過MQSeries與其相連,規範了程式設計接口,使系統具備最大的可連接配接能力,在實際應用系統中,各子系統通過MQ程式設計接口,把自身的資料作為資料源傳輸至MQSeries Integrator,MQSeries Integrator采集到該資料後,根據客戶自己定義的規則智能地分發給需要該資料的應用子系統,資料的傳輸依然是基于MQSeries,其它子系統接收到的資料已經是經過MQSeries Integrator的格式轉換,能直接處理的資料。

所有需要與政務資料中心進行脫機交易、批量資料處理 <script type="text/javascript"> </script> 、資料交換的系統均安裝MQ Series與資料交換中心相連接配接(可以是撥接上網、ISDN、DDN、幀中繼等任何連接配接方式),實作與政務資料中心和其他系統的可靠資料交換。這些系統可能包括政府系統的各個部門。

3)、通用的資料交換器的結構:在電子政務系統中,多數情況是異構資料庫之間的資訊交換。一般要在各機關的伺服器上加上工作站擴充卡(Adapter)實作異構資料交換、安全認證、傳輸前後的打包、解包等功能。下圖中每一個資訊交換平台即為一個擴充卡。而擴充卡間的協調監控由注留在中間件伺服器上的相關控制器完成。

3)自成體系的交換平台

利用多層結構體系、J2EE+XML、Web Service、資料庫等技術,構造資料交換、資料流引擎和資料中心系統,資料交換、資料流引擎與資料中心統一構造為"可信資訊交換平台" 實作電子公文與政務綜合資訊的共享和交換,為并聯審批等業務提供支援。

本方案有一個資料交換平台和一個任意可裝配的擴充卡組成。原理圖如下

擴充卡的主要功能設計:

1) 資訊交換器:實作不同格式的檔案向XML的轉換或反之,對大容量檔案進行拆分或合并。

2) SOAP服務:按SOAP格式打包或拆包

3) 安全認證:調用相關API進入CA認證

4) 密碼服務:加密、解密或壓縮

5) DB通路代理:對典型資料庫提供通路接口(JDBC、ODBC)

6) 工作流引擎:為工作流引擎的同步/異步、協同工作提供服務

平台管理器的主要功能設計:

1) 消息管理:管理消息隊列,同中間件伺服器中的消息管理協調工作

2) 使用者管理:管理聯接到伺服器的使用者,設定通路權限

3) 模型管理:管理根據應用中的表格以及各種表格的轉換模型

4) 監控管理:運作狀态、運作流量、負載能力、日志等的管理

資料的透明交換涉及資料格式、資料結構、資料語義的統一定義,涉及傳輸的路由、資料傳輸的同步/異步、資料傳輸的負載均衡等技術問題,需在設計時根據具體情況而定。

posted @ 2007-06-06 10:11 wangyan 閱讀(15) | 評論 (0) |  編輯  收藏  

.net開發過程中,錯誤集錦 2007年7月10日 System.Data.OracleClient 需要 Oracle 用戶端軟體 8.1.7 或更高版本 2007年6月25日 2007年6月11日 2007年6月8日 2007年6月6日 應用程式結構 向應用程式中添加預定作業生成Web服務生成Windows服務擴充流程層以處理預定作業作業計時資訊檢索和設定作業計時資訊調用作業計時存儲過程處理預定作業小結作者簡介資料交換中心的方案設計 2007年5月31日
2007年5月31日

使用 Anthem.NET 的常見回調(Callback)處理方式小結[轉]

使用 Anthem.NET 的常見回調(Callback)處理方式小結[轉]

轉自:http://www.cnblogs.com/RChen/archive/2006/09/12/anthem_callback.html

在 Anthem.NET 中,通過 XmlHttp 或 XmlHttpRequest 元件對伺服器端所作的一次無重新整理調用(通常是異步模式),稱為一個回調(Callback)。

本文内容是對 Anthem.NET 架構自帶範例代碼的整理和歸納,着重小結一下在使用 Anthem.NET 進行 Ajax 開發的時候所涉及的調用流程控制相關的内容。至于控件的使用,因為邏輯簡單,這裡不做叙述。

在本文後,計劃寫一篇文章對調用流程及其程式設計時的可控制點做比較完備的歸納。

一、普通的調用

<%@ Register TagPrefix="anthem" Namespace="Anthem" Assembly="Anthem" %>

<anthem:Button id="button" runat="server" Text="Click Me!" />

<anthem:Label id="label" runat="server" />

<script runat="server"> void button_Click(object sender, EventArgs e) {     label.Text = DateTime.Now.ToString();     label.UpdateAfterCallBack = true; } </script>

二、在回調前後添加自定義用戶端函數的執行邏輯 幾個常用的屬性: PreCallBackFunction:用于定義回調前執行的函數,通常可以在這裡加入确認的判斷。                      在這個函數裡 return false 将會取消回調。 PostCallBackFunction:   回調後執行的函數。 TextDuringCallBack:    用于定義回調過程中控件顯示的提示資訊(通常是提示等待的文字) EnabledDuringCallBack: 在回調過程中,控件是否禁用。 CallBackCancelledFunction: 如果回調被取消,則會調用這個函數。 代碼例子:

<anthem:Button id="button1" runat="server" Text="Click Me!" TextDuringCallBack="Working..." EnabledDuringCallBack="false" PreCallBackFunction="button1_PreCallBack" PostCallBackFunction="button1_PostCallBack" CallBackCancelledFunction="button1_CallBackCancelled" />

<script language="javascript" type="text/javascript">

// 回調之前,可在這裡取消回調

function button1_PreCallBack(button) {     if (!confirm('Are you sure you want to perform this call back?')) {         return false;     }     document.getElementById('button2').disabled = true; }

// 回調完成後 function button1_PostCallBack(button) {     document.getElementById('button2').disabled = false; } // 取消回調後

function button1_CallBackCancelled(button) {     alert('Your call back was cancelled!'); }

</script> 注意以上這些用戶端處理函數中,都可以傳遞 control 本身作為參數,是以在必要的情況下這些函數是可以被重用的。(比如對一組類似的控件的回發事件進行處理) 三、調用伺服器頁面的方法 伺服器端需要做的事情:

[Anthem.Method] public int Add(int a, int b) {     return a + b; }

void Page_Load() {     Anthem.Manager.Register(this); } 用戶端:

<input id="a" size="3" value="1"> <input id="b" size="3" value="2"> <button onclick="DoAdd(); return false;" type="button">Add</button> <input id="c" size="6">

// 參數的含義依次是: //     伺服器方法的名字, //     方法的參數(以 js 數組形式傳遞), //     伺服器端方法傳回結果時調用的回調函數(因為是異步模式)。

Anthem_InvokePageMethod(     'Add',     [document.getElementById('a').value, document.getElementById('b').value],     function(result) {         document.getElementById('c').value = result.value;     } );

調用後,在回調函數的參數中得到的 result 變量,是一個包含 value 和 error 兩個屬性的對象。如果在伺服器端發生錯誤,則 value 為 null, 而 error 中包含錯誤資料。

四、如何處理回調時可能發生的異常

在頁面中定義 Anthem_Error js 函數,則可處理所有回調時的未處理異常。

<script type="text/javascript"> function Anthem_Error(result) {     alert('Anthem_Error was invoked with the following error message: ' +          result.error); } </script> 異常也可以在伺服器端處理。隻要定義下列名稱的方法: void Page_Error() {     Anthem.Manager.AddScriptForClientSideEval("window.location = 'http://anthem-dot-net.sf.net/'"); } 在伺服器端處理有一些額外的好處,主要是可以将異常資訊記錄到日志. 五、頁面跳轉 在 Callback 的進行中,不能用 Response.Redirect 來處理頁面跳轉,因為這些函數是通過 js 的無重新整理來調用的。代替的辦法是用 Anthem.Manager 回傳一段 js 給用戶端去用 eval 的方式執行,進而達到頁面跳轉的效果(推而廣之,這個 eval 的功能當然不限于跳轉頁面,可以幹很多其他的事情)。 代碼示例: Anthem.Manager.AddScriptForClientSideEval("window.location = 'http://anthem-dot-net.sourceforge.net/';"); 六、幾個全局級别的用戶端回調函數 我們可以在用戶端定義幾個特殊名字的函數,以供 Anthem 在每一次回調的前後調用。這些函數包括: Anthem_PreCallBack(), Anthem_CallBackCancelled(), Anthem_PostCallBack(), 除此之外還包括前面說到的 Anthem_Error() 等。 這裡典型的一個應用場景是,在每次回調開始後,我們在 Anthem_PreCallBack() 中建立一個“loading”資訊的層,然後在取消(Anthem_CallBackCancelled) 或成功回調後(Anthem_PostCallBack),移除這個層。 這樣可以很友善的模拟出類似 Gmail 中的加載效果。 七、回調過程中向頁面添加了新的 js 腳本 這種情況下必須設定一個額外的屬性: Anthem.Manager.IncludePageScripts = true; 例子: <script runat="server"> protected void button1_Click(object sender, EventArgs e) { HtmlButton button = new HtmlButton(); button.InnerText = "Now click me!" button.Attributes["onclick"] = "ThankYou();" placeholder1.Controls.Add(button); placeholder1.UpdateAfterCallBack = true; string script = @"<script type=""text/javascript""> function ThankYou() { alert('Thank you!'); } </" + "script>" #if V2 Page.ClientScript.RegisterClientScriptBlock(typeof(Page), script, script); #else Page.RegisterClientScriptBlock(script, script); #endif Anthem.Manager.IncludePageScripts = true; } </script> 八、PreUpdate 事件 控件在 Render 之前,如果 UpdateAfterCallBack 為 true,則會引發這個事件。 目前這個事件的用途似乎不大。

posted @ 2007-05-31 15:52 wangyan 閱讀(18) | 評論 (0) |  編輯  收藏   [轉載]ASP.NET中為GridView添加删除提示框   在GridView中我們可以直接添加一個CommandField删除列來删除某行資訊。但為了避免誤操作引起的誤删除,在删除操作者讓操作者再确認下,完後再進行删除。

  首先我們給我們的GridView 添加一個模闆列,如下:

以下是引用片段:

<ASP:TemplateField HeaderText="Delete" ShowHeader="False">

<ItemStyle ForeColor="Red" />

<ItemTemplate>

 <asp:LinkButton ID="BtnDelete" runat="server" CausesValidation="False" CommandName="Delete"

Text="Delete"></asp:LinkButton>

</ItemTemplate>

</asp:TemplateField>

  其次我們給我們所添加的模闆列添加:OnClientClick="return confirm('确認要删除此行資訊嗎?')" ,如下:

以下是引用片段:

<asp:TemplateField HeaderText="Delete" ShowHeader="False">

<ItemStyle ForeColor="Red" />

<ItemTemplate>

 <asp:LinkButton ID="BtnDelete" runat="server" CausesValidation="False" CommandName="Delete"

Text="Delete" OnClientClick="return confirm('确認要删除此行資訊嗎?')"></asp:LinkButton>

</ItemTemplate>

</asp:TemplateField>

  點選删除時就會先在用戶端彈出“确認要删除嗎?”對話框,一般我們确認删除。