Sharepoint 客制化筆記 (1) Event Receiver


最近整理過去客制化Sharepoint 2007的成果,
覺得當中有些小撇步,值得被記錄下來並且分享給其他Sharepoint開發者。


(1) 事件監視器 Event Receiver



事件監視器指,當項目(Item)或清單(List)發生變動時,會被呼叫的一組API。
一般來說使用C#配合Visual Studio開發的情境下,可以透過繼承方式自定行為,並以wsp型式部署至Sharepoint執行環境。

這裡個人推薦一個codeplex上可以下載到的plugin: Power EventReceiver

這位名為iLoveSharepoint的作者,將許多需要用C#撰寫的事件,改為用PowerShell Script就可以撰寫,PowerEventReceiver只是其中之一,接下來其他篇還會介紹這位作者其他好用的Plugin。

對於C#的開發者來說,乍聽之下會覺得「我C#寫好好的何必再多學一種語言?」
但是我實際使用這個plugin之後,發現它提供的好處讓我決定「就改用PowerShell吧!」

好處有哪些呢?

1. Deploy很方便,基本上就是一堆Copy&Paste而已,你只要把寫好的Script貼到這個Plugin提供的pure text editor就好了!
這個Plugin會把你的script當作一個config檔,執行階段動態load進來開一個PowerShell session執行。

2. 既然Deploy這麼簡單,當然也沒有stsadm, iisreset之類的指令操作,可以把maintenance  downtime縮短到最快。

3. 這個Plugin 裝好以後,每個List可以個別自訂需要的行為,不用針對不同List撰寫不同的dll/wsp。

4. Event log那些的它都幫忙處理好了。

5. 甚至連你把List打包成stp檔的時候Script都會被帶著走。


這裡解說一些我自己在撰寫Event Receiver時常遇到的問題:
(以下syntax都是PowerShell)

ItemAdding與ItemAdded: 

ItemAdding在收到Create Form Post過來的資料之後發生,這時候項目還沒有被新增到DB, 所以存取項目屬性的方法不是$item.title,而是$properties.AfterProperties["title"]

當然,$item.ID也只能在ItemAdded裡存取到,原理很簡單想一想就知道啦。


這個小麻煩詢問度很高,只要下對關鍵字,一般都Google得到解。

Item Updating與Item Updated: 


狀況大致跟上面一樣,$item.title取到的是更新前的資料,$properties.AfterProperties["title"]取到的是更新後的資料。

這裡需要注意的是,Item*ing發生在項目被寫入資料庫之前,如果要對項目內容作可用性檢查(validation),應當將行為寫在Item*ing中,而非Item*ed.

那如果做了驗證之後決定退回呢?
$properties.Cancel = $true
$properties.ErrorMessage  = "Item of the same title exists!"

這樣使用者就會在按下Post之後看到 Item of the same title exists!


ItemDeleting與ItemDeleted:


ItemDeleting比ItemDeleted有趣的一點是,$item.ID只有在ItemDeleting裡取得到,如果想在項目被刪除時發信通知,這裡是最後可以存取到ID的機會。


安裝與部署

Power EventReceiver的部署方式與一般wsp無異,
一樣需要本機端Admin操作cmd模式進行,安裝後需要iisreset
安裝後每個Site可以根據實際需求到site feature裡打開/關閉這項功能。

每個List更新自己的Script時,不需要iisreset與deploy,
Script本身的部署界面在List的List Setting頁面裡,不過需要SPAdmin等級的權限才看到。
Script執行時的權限與觸發事件的使用者相同,通常也就是Item的CreatedBy那個帳號。

剩下的問題請參考iLoveSharepoint的Codeplex頁面,寫得很清楚。

留言