2008年12月26日

直接操作 Gridview 上的 增刪改 (程式碼篇)

由於廢話 上一篇 都講的差不多了 直接進入程式碼的部分吧
首先來回憶一下頁面上的配置

主要要寫的事件有 新增 修改 刪除 三個功能鍵
新增事件為 將上方輸入的資料 加入至 Gridview 中
修改事件為 將資料放至上方輸入框中 再按下上方的 新增 鍵 修改其資料
刪除事件為 將 Gridview 中該列資料給刪除 (廢話

先看來 新增 的按鈕事件
由上面所述可得知 這個按鈕會觸發 新增修改 兩個事件

首先 建立 DataTable 當 Gridview 的 DataSource 來源

接著這段是從目前的 Gridview 中把資料抓到 DataTable 中
這邊可以看出坎尼的動作很簡單
Gridview資料->DataTable->增刪改->指定給 Gridview

另外 坎尼用 CommandArgument 的有無 判斷目前的狀態為何

可以看到 CommandArgument 記錄的是 order 只要減1就是 RowIndex
index 相同時 則把上方修改過的資料填入 DataTable 中
否則把 Gridview 裡的資料取出來填入 DataTable 中

這邊會看到坎尼都會加上 Replace("& nbsp;" , "") 這段
這是因為 Gridview 資料繫結後 會在資料上加入個空白
以防沒有繫結時 Table 表格該格的顯示上會不好看
(想試的人可以把 replace 這段拿掉 看回填的資料長怎樣)

接下來還是同一個事件喔 其實看註解就差不多了 (逃


接著來看修改按鈕的事件 (謎:你還真的跳過不講了)

其實這個事件是和上面的 btnAdd_Click 事件有關
按下 Gridview 上的修改按鈕時 會先把原資料導到上方

所以這裡就是先利用 CommandArgument 找到該列的資料
再將資料填入上方的 資料輸入裝置組 (好像樂高玩具的感覺
剩下的步驟就是由 btnAdd_Click 去判斷是否為更新資料了

最後就是刪除資料
這裡比較單純 只是 Gridview 把資料回填到 DataTable 時 跳過該列即可

以下是執行畫面
修改前 有人發現坎尼謊報年齡 而且想加個動詞
(這邊可以看到 原本的 新增 鍵的文字改為 修改)

修改後 坎尼的資料確實被修改了 (新增鍵的文字又改回來了)

編資料的人對坎尼很不滿 想要直接刪除坎尼的資料

按下確定後 坎尼就蒸發消失了
這邊要注意順序不會因有人被刪除而亂掉
而是將後面的人序號往前推


最後把資料存入資料庫這段坎尼就不寫了
流程是 從Gridview取得資料 -> ADO.NET

以前有看過同學寫過 在某個頁面 要加入新的人員資料
那時同學是放個 "新增" 按鈕 按一下就跳出一組資料輸入 (上圖的資料輸入裝置)
要多幾個人就按幾下 儲存時還要判斷資料有沒有填入
雖然動態抓控制項沒有說很難 但不符合坎尼的風格 囧興

現在用這種作法雖然程式碼煩人了一點
但在畫面的呈現上坎尼是覺得好很多

補了兩篇回來 不過這週 Tim 抓狂的放了好多篇
等坎尼案子趕完再來追一下篇數 XDDD

最後補上個 source code 下載

直接操作 Gridview 上的 增刪改 (前言)

剛剛被 Tim 嗆說他這個月的文章數大勝
坎尼雖然月底要做好個案子 也只好放下工作來發個兩篇

話說這篇還真的不知道該怎麼去下標題 (汗
主要的精神就是 不經由 DataBase 來對 Gridview 做操作
由於內容很多 所以就不廢話了 直接進入主題

首先 在頁面上配置 資料輸入裝置 (也就是上方的 TextBox 們
以及 資料顯示裝置 Gridview

來看一下 資料顯示裝置 Gridview 的裝備 啊 是設定
除了上方輸入框的三個屬性外 還多加了個順序

並且加上了個 TemplateField 放入了 修改 刪除
兩個 LinkButton CommandArgument 繫結了 order 欄位

好了 準備完成 初心者可以準備出村外了
也許有人會有疑問 這和一般的 Gridview 配置有啥不同?
「當然相同啊!」坎尼極度的肯定 (背後響起了拔刀的聲音...
不過在資料存取上 並不是由資料庫做連結

以上圖的設計一般來講流程會是 新增->資料填入資料庫->取出做 Bind
但本篇的設計則是要去除資料庫這塊 直接操作 Gridview 的物件

此種設計用途在於
資料集合只是使用者暫存的輸入 要等到最終的 Save 按下才會存入 DB之中
若是用上述的第一種方式 每增加一筆就要進 DB 兩次 (Insert + Select)
最後要是使用者選擇放棄儲存 又要去把剛剛 Insert 進去的資料 Delete
DB Server 又不是閒閒沒事一直在處理這件事 XDDD

所以坎尼想到了先用 Gridview 儲存使用者的暫存資料 並可 增 改 刪
最後使用者確定儲存時 再將 Gridview 裡的資料批次送進 DB 裡
若是使用者填一半後悔按下放棄時 就直接讓 Gridview 裡的資料隨風去.....

本來想說解釋一下 沒想到已經講這麼多了 囧>
如果再講 source code 可能會讓篇幅過長
先看一下執行畫面吧

上圖完全沒有透過 DB 來達成 有興趣的人請等待 下篇

2008年12月25日

最近很紅的 SQL Server 漏洞 + 如何訂閱 Microsoft Security Advisory

最近跟 SQL Server 有關的新聞不少,一開始我是在一個印度的 SQL Server MVP 的 Blog 上看到關於 SQL Server 2005 SP3 的消息(12/18),沒想到很快的在 12/22 就收到微軟的窗口的 mail,提醒說微軟已經發布 Security Advisory 961040,結果昨天(12/24) iTHome 就已經看到相關的中文報導,還有祭司的 blog 上也有相關消息,最後是今天在保哥的 blog 上也看到相關的消息了,看來有在隨時注意新知的人都能很快跟上進度。

看以上那些報導就可以對這個漏洞有一定程度的瞭解,所以我就不多廢話了,
主要是今天忽然想到,到底 MS Security Advisory 有沒有 RSS Feed 可以訂閱呢?
 
於是我連回 Security Advisory 961040 的網頁,點了網頁上方的 Security Advisory 連結:
Microsoft_SecurityAdvisory

果然順利找到了 RSS Feed:
Microsoft_SecurityAdvisory_RSS

接下來又看到下面還可以訂閱 Windows Live Alert,於是繼續點進去(登入頁略):
WindowsLive_SecurityAlert_Choose

直接全選之後,還有進階設定,我就繼續全選:
WindowsLive_SecurityAlert

最後設定完成的樣子:
WindowsLive_SecurityAlert_MyAlerts

這樣以後就更不容易 miss 掉微軟重要的姿安訊息囉!
最後補充一下前天安裝 SQL Server 2005 SP3 的心得:
  • 安裝前大約花了 1.5 HR 看了 Readme, Installation Guide
    (裡面有說,裝了 SP3 之後,若 SQL Server 相關 Component 發生異常,則無法修復,請整個 server 砍掉重練。雖然聽起來有點恐怖,但發生機率應該極低)
  • 裝的過程大約 30 ~ 45 分鐘,沒什麼困難 (No SSAS, SSRS, Failover Cluster)
  • 共安裝兩台,一台從 RTM –> SP3,另一台從 SP2 –> SP3,裝完都沒甚麼副作用
  • 還沒有安裝的朋友,趕快安裝吧!!

2008年12月22日

[ASP.NET] Session 變數在網站(子)目錄更名/刪除後消失 (InProc Mode)

       最近處理了一個 Session 變數會莫名消失的問題,麻煩的地方在於,這個舊系統在.NET 1.1的環境上活的很愉快,但是努力升級到.NET 2.0之後,在某些狀況下 Session 變數就會莫名的消失,導致權控子系統判斷為 Session Timeout,而將 user 自動登出系統。(不會留下任何的Event Log / Error Log)

      遇到這種問題,當然首先要先釐清到底在甚麼狀況下 Session 變數會消失?一開始大家猜測是 ASP.NET 1.1 和 ASP.NET 2.0 的 Session 有不同的運作機制(升級到 .NET 2.0 之後系統就掛了),這個大方向是對的,但最後發現問題的癥結其實跟 Session 的運作機制無關,Session 變數消失只是一個很糟糕的副作用罷了 …

經過反覆的測試,最後終於將範圍縮小至「呼叫一個 WebService (撈外部系統的資料)」後,便會造成 Session 變數消失。此時一位資深的同事注意到,由於外部資料可能常常會有變化,因此系統有一個特殊行為是會將 WebService 回傳的資料寫入一個暫存目錄中,而每次呼叫 WebService 前都會先將整個暫存目錄(及其中的檔案)刪除,而這就是造成 Session 變數消失的關鍵!(跟權控子系統一點關係都沒有)

經過一番 Google,發現這個 Session 變數會消失的問題最早大約在 2005 年就開始被討論,原因是從ASP.NET 2.0 開始新增的「Dynamic Compilation」機制,此玩意兒是指 ASP.NET (2.0+) Runtime 會持續監控應用程式的根目錄(Application Root Folder)以及其下所有的子目錄,出於安全性的考量,當這些目錄被更名刪除時(不管是手動修改或是在 runtime 以程式修改),都會造成 Application Domain Restart!(也就是整個網站瞬間 shutdown、重新 compile 之後,再啟動)

當整個 w3wp process 都被砍掉重練了,Session 自然也不能倖免,直接就被刪除重建,其中的變數更是整個屍骨無存,最後導致 User 自動被登出系統。
      在瞭解了基本觀念之後,又有資深的同事們提出了幾個更深入探討的方向,包括:
      因此接下來又整理出以下各種 scenario,並逐一進行測試(X表示Session會被刪除重建,範例程式下載)。在開始進行測試之前,我的預期是,sessionStateMode 主要的差異在於儲存位置的不同(因此影響 scalability),儲存位置的差異對 ASP.NET Session 物件的運作機制應該沒有影響,因此不管選擇將 Session 的資料存在哪裡,在 Application Domain Restart 的時候,應該全部都會被清空吧!(這樣的話開發人員就不需要特別為了不同的 sessionStateMode 而設計不同的 Session 變數管理方法了)

以下為測試結果:
                                        SessionStateMode
Deployment Style
InProc StateServer SQL Server
Copy Web Site (直接將 Source Code 佈署出去) X
Pre-Compilation (for deployment) X
Pre-Compilation (for deployment and update)
(等於執行Visual Studio 內建的 Publish WebSite)
X

      但是!事情並不是懶惰的我所想的那麼簡單!由以上的測試結果可明確的看出:選擇不同的 sessionStateMode 對 Session 變數會有截然不同的影響!在 sessionStateMode 採用「InProc Mode」時,只要更名(或刪除)網站的子目錄就會造成 Application Domain Restart(新增、刪除檔案則沒有這個副作用),若採用 StateServer/SQL Server 來儲存 Session 資料,則不管 Application Domain 如何反覆的砍掉重練,Session 變數還是可以堅忍不拔的活的很快樂!(其餘的 sessionState 屬性都採用預設值

結論:
     
ASP.NET 2.0+ 的 Dynamic Compilation 行為是無法被改變的,若系統採用「InProc Mode」來儲存 Session 資料,且想要用程式在 runtime 清除暫存資料可以採取以下兩種作法:
  1. 迴圈的方式刪除暫存目錄下的所有檔案,不要把暫存目錄整個刪除,此作法的effort 較小,亦可將暫存目錄設置於網站根目錄下一併管理。
  2. 將暫存目錄的位置移出網站的根目錄,如此便可任意更名/刪除此暫存目錄,缺點為管理上的 effort 較大(多一個虛擬目錄要管理)。
後記:
 
      我不太懂為何 ASP.NET 會設計成,當採用 StateServer/SQLServer Mode 時就不清空 Session 資料。這樣就表示不同的 sessionStateMode 所代表的不僅僅是 Session 資料的儲存位置不同,連帶的 ASP.NET 對於 Session 資料的管理策略也是不同的,感覺對於開發人員來說這會是一個額外的負擔。

      從效能的觀點來看,若系統中有某個功能一旦被執行就會造成 Application Domain Restart,那絕對不是甚麼好事。但是在開發階段只有採用「InProc Mode」或者已經事先深入瞭解 Dynamic Compilation 的運作機制,才能避免效能低落的程式寫法。若是經驗不足,或是不小心採用了 StateServer/SQLServer Mode,那麼系統只會默默的把 Application Domain 砍掉重練,不會丟出任何警告訊息,也不會寫下 Event Log,而Session 變數的內容看起來都會是很正常的!(權控子系統都可正常運作)那麼效能也只能默默的變差了 …

      為了補足 ASP.NET 預設對於 Application Shutdown 事件不會寫 log 的缺憾,我在Microsoft Developer Division 的 VP - Scott Guthrie 的 blog 找到了一個方法,在Global.asax的「Application_End」事件中將Application Shutdown的資訊寫入到Event Log,如下圖所示,如此便可明確看出 Application Shutdown 的原因是因為「dir change or directory rename」:
ApplicationShutDown

Reference:
  1. ASP.NET Application Life Cycle Overview for IIS 5.0 & 6.0
    (See Community Content #1)
  2. Logging ASP.NET Application Shutdown Events
  3. ASP.NET Deployment Overview
  4. sessionState Element

2008年12月21日

Sara Ford 的 Visual Studio Tips 系列結束囉

前天看到 Sara 的 blog 上 po 了最後一個 VS 小技巧 (#382), 講的是如何從Command Prompt下指令執行”System Information”(好像沒甚麼用XD), 同時也宣告 VS Tips 系列的結束,剛剛用 Google Reader 看了一下她的 blog, 「Did you know…」系列的第一篇文章大約是 2007年7月發表的, 所以 382 個小技巧大約寫了將近一年半(都是用她自己的下班時間), 真是令人佩服(跟保哥有得拼)。

不過她又講說,明年會再另外開一個 blog 來延續這個系列@@
看來之後還是有辦法以多多學習如何增進使用 VS 的工作效率囉 ^_^
VS 中有非常多好用的小技巧,若不靠他們這些熟知內情的專家的說明的話,
相信一般人根本就不會注意到,而Sara自己也常說,很多技巧對她來說也很難發掘,
必須要追根究底的去問 VS Team 才能瞭解如何使用,所以這些技巧真是得來不易呀!
善用工具可以大大增進工作的效率,如果沒有看過她的 blog 的朋友,
建議抽空去晃晃,可以先看一下標題,很可能剛好就 hit 到你的需求哦!

以下是一些我覺得蠻有用的小技巧:

2008年12月16日

Microsoft patterns & practices - Application Architecture Guide 2.0 Released!

這是今年老闆丟給我們看的一份文件,年中的時候還只有 1.0,不過今天發表了 2.0 囉!
雖然這份文件份量蠻多的 (387頁),不過內容很充實,有空的話應該要花些時間讀一下。

稍微瞄了一下,除了傳統的 Layer & Tiers Archetype,這次的 release 強調 RIA 的部份,但是很奇怪的用了 Rich Internet Application 這個 Macromedia (Adobe) 提出來的 term,而不是微軟用的 Rich Interactive Application,結果查了一下 Wiki 之後發現, 目前看來應該是 Adobe 的 term 勝出了吧 XD (PS. SL3 的 3D 效果還蠻炫的)

App Arch Guide 內容如下:
Parts
Part I, Fundamentals
Part II, Design
Part III, Layers
Part IV, Archetypes
Forewards
Chapters
Part I, Fundamentals
Part II, Design
Part III, Layers
Part IV, Archetypes
Appendix

如何在 .NET 後端處理時加上等待訊息

坎尼的同事問到這個問題
由於舊系統的資料量太大 每次 Query 都會等待一段時間
可是 user 有時卻等不及想再按一下
這時除了讓所有 button diable 的方法 (請參考 這裡
還可以利用簡單的提示訊息 讓使用者明白目前的系統正在運作

由於舊系統是以 vs 2003 做開發 要加入 Ajax 套件的功能有點麻煩
所以坎尼想到了用 javascript 來控制訊息

這邊要提一下 Webform 執行指令的先後順序
當按下一個 asp button 要送回後端處理時
此時瀏覽器會優先執行 button 上的 javascript
(其他控制項的先後順序當然也是這樣)
所以可以利用 控制項Attributes.Add() 方法 加入前端觸發的事件
以下就按下 button 然後產生文字提示作示範

首先在畫面上佈置一個 label 及 button 控制項
坎尼把 label 的文字顏色改為 紅色 這樣比較醒目

接著在 page_load 事件加上前端的 onclick 事件
(若是使用 vs 2005 以上版本 button 可以改用 OnClientClick 屬性)
這邊可以看到 坎尼在按下 button 時 利用 javascript 將 label 的文字改變
另外第一句註解的地方 是 jquery 的寫法


再來看按下 button 的事件
這邊可以放置後端處理事件的 code (範例是利用 Thread 讓整個程序睡5秒
記得在事件結束前 把 label 的文字改為 「載入完成


以下是實際執行情況


由於客戶只要求能有個提示就好 所以坎尼也只幫同事研究到這邊
其實這類的應用應該古早以前就有人寫過了吧? (坎尼還沒 Google 過

除了文字改變的表示外
還可利用 javascript 去控制 css 樣式
讓文字標籤出現完成字樣後 再慢慢的淡出
(將顏色改為和背景色相同 或是改 alpha 值 有興趣的人請自行測試
更懶的人可以直接用 display 的屬性讓 Label 消失

(以下碎碎念
近年出現了許多很炫麗的網頁技術
但在寫程式之前 其實可以先思考開發的便利性及功能性
此類簡單的應用勝過研究許許多多的新技術 只為了導入一個簡單的功能
花費的時間人力成本可能勝過原本的想像

坎尼也是很喜歡去學新技術
不過還是不要只 Google 了一下 囫圇吞棗完就準備上陣
許多基礎原理還是要弄懂 免得後來 debug 到天明 :p

2008年12月14日

訓練程式邏輯 – Light-Bot

最近在好幾個地方都不約而同的看到有人推薦 Light-Bot 小遊戲,
說是可以訓練程式邏輯,玩了一下覺得還不錯(共12關),說明畫面是這樣:

image

關卡長得像這樣:

image

右邊有一個「MAIN METHOD」的區塊,就是最後執行的程式,
下面可以自訂「FUNCT.1」和「FUNCT.2」(這應該不用多解釋吧XD),
遊戲目標是要透過 MAIN METHOD 操縱畫面上的機器人走到藍色的格子上去點燈,
機器人可做的動作就是右上方那七種,用拖拉的方式拉到下面的程式區塊即可。

基本上關卡都不太難,不過我莫名的在第六關卡了一段時間,
而且之前同事寄給我第10關第11關的破關方法,害我很懶惰的跳過了第11關 Orz

Anyway,最後我在第10關的作法跟同事寄給我的不一樣(但是忘記抓圖了=.=),
很明顯的每一關都可能有好幾種解法,真的要比的話應該要比誰用的步驟最少,
不過這樣玩起來就有點太過嚴肅了 XD

如果不想在網頁裡面玩的話,也可以到這裡下載

WorldCommunityGrid(WCG) – The Clean Energy Project

話說…今年七月中的時候寫了一篇介紹 WCG 的文章,當時run了一個月左右,
排名在17萬多,不知不覺已經run了半年(2008/6/14 ~ 12/14),
排名變成2萬5千多,似乎很難再進步了 XD (砍泥這個偷懶的傢伙進步更慢…)
之前run的時候發現一件麻煩的事情,就是WCG Client必須要用administrator身份執行
因此每次開機就會在 Notification Area (工具列最右邊的區塊,一直搞不懂中文叫啥 =.=)
看到 WCG Client被禁止執行的訊息,真的是被這個UAC的機制搞得很煩,
但是為了安全只好每次都手動去啟動 WCG Client,但是現在可以避免這個麻煩 囉!
前陣子在看log檔的時候發現,有出新版的 Client,而且好像有接到新的project的task,
於是上去了久違的WCG官網,果然出了最新的「6.2.28 版」Client,更新之後發現,
現在不需要administrator的權限就可以順利的執行 WCG Client 囉!
相信這個修正對於使用 Vista 以上 OS 的 member 來說是個大好消息,
雖然 Vista 出了這麼久,這個更新來的有點慢 XD
(在 Win7 Blog 上 10 月初對 UAC 的討論中提到,目前大部分的軟體都已經不再需要 administrator 權限就可正確執行了,對於系統安全性有很大的幫助。)
除了 Client 的改進之外,前陣子也推出一個新的 project –> Clean Energy Project
剛好搭上最近很熱門的能源議題,感覺現在開始 run 是有點慢了 Orz
這個 project 是要利用電腦作分子的物理性質和電子結構的運算,
試圖找出最適合用來作為下個世代的太陽能電池的材料,
聽起來蠻複雜的,希望可以很順利的進行下去~
喔對了,WCG 計畫現在已經有 41萬8千多個 member (台灣有 2,293 人),
註冊的機器超過 114 萬台 (台灣有 11,044 台),累積運算時間超過 20 萬年,
共完成超過 2億2千萬個 task (統技數據)。

2008年12月9日

用javascript做下拉式日期選單

前兩週是坎尼爆肝週 晚上回去大多是該睡覺的時間 orz
發現已經積了不少篇文章 可是卻沒時間可以講 囧>
(而且坎尼的電腦灌 Vista 64 一直抓不到驅動 怒

今天來講個老梗吧
如何用 javascript 做下拉式日期選單

首先要了解月份的算法 1月大 2月小 3月大...... 相信大家幼稚園都有背過這個
不過這之間的例外就是2月 它每四年就會多一天 (也就是閏年
閏年的算法為 西元年 可被 4400 整除 但不被 100 整除
(想當年 坎尼和Tim的計概期末考是考這個 囧興

直接來看抓圖吧


首先在頁面上佈置三個 DropDownList (當然也可以用 select 來做
重點是要給它們一個 id 並把 id 傳入待會要講的 javascript function 中
這邊 onload 事件是初始時 判斷月份的天數
若後端在初始化時已經做完 這邊有沒有加入事件倒是沒啥差


後端初始化下拉選單的選項 並將選擇日期預設為今日

接著三張為 javascript 同一個 function
可以看到 function 要分別傳入 年 月 日 的下拉選單 id
這邊是為了較有彈性而設計 以免換頁面 id 不同 又要開.js 檔出來改
另外 create 三個 option 是用來增減天數選項 (因為會變的只有 29 30 31)

由上圖可以看到 若是為閏年
日期的下拉選單會加入 29 的option
反之 將 index 28 移除 (也就是第29個項目)

下面兩張同理 所以就跳過



突然發現 好像講完了 orz
.js 請到 這邊 下載

用下拉選單的好處就是 可以在三個動作就到達要選的日期
壞處就是.....它一定至少要三個動作 (日期不同的話)
然後一般以表格化的月曆 (也就是和 .net 的 calendar 長很像的那種)
缺點是 若是要點 1960 年的日期 可能要點上一年點到死掉 XD
但優點就是很直觀 所以網路上已有人將兩種方式結合起來

最後再提一下 AJAX Control Toolkit 的 CalendarExtend 就是這種
不過動作只要把 Extender 拉到畫面上 然後指定 TargetID就好
真是好用又簡單啊

Google Spreadsheet 裡用規則運算式

最近因為工作關係,遇到要用 Google Form 及 Google Sheet 所以研究了 Google Sheet 裡的一些 function 怎麼用 首先,分享一下如何在 Google Sheet 裡用規則運算 :D