CODE-C# 程式讀取 Exchange 共用行事曆

工作遇到新需求:辦公室自動化服務希望讀取使用者行事曆,整合顯示於個人資訊頁。

EWS Managed API 封裝了複雜又囉嗦的 Exchange Web Service SOAP 細節,改以 .NET 程式庫形式提供電子郵件、連絡人、行事曆、公用資料夾的存取管道,是 C# 開發 Exchange 相關程式的首選。(意外發現 EWS Managed API 從 2014 起轉為 Github 開源專案,有原始碼在手,搞不懂走不通都有救,用起來格外讓人放心,微軟真的愈來愈開放)

官方文件有篇詳細介紹文,示範如何使用 EWS Mananged API 查詢行事曆取得個人約會資訊。基本原理是利用 CalendarFolder.Bind() 連上個人行事曆,接著建立一個 CalendarView 指定查詢期間、取回筆數,CalendarView.PropertySet 則傳入要讀取的欄位(主旨、開始/結束時間… 等),接著呼叫 CalendarFolder.FindAppointments() 就取得 Appointment 的集合,很簡單,這部分可直接參考官方範例。好消息是 EWS Managed API 用 NuGet 就可以下載:

不過我的需求多了一些變化,系統會使用統一中間程式查詢不同使用者的行事曆,而我們不可能為此要使用者交出 AD 帳號密碼。因此,透過行事曆共用是較可行做法。

行事曆共用可使用 Outlook 操作, 找到自己的行事曆(一般會有兩份,要選名稱有個人郵件地址位於 Exchange Server 的那一份),右鍵選單開啟內容:

程式使用 EWS Managed API 會以特定 AD 帳號執行(測試時可用開發者自己的帳號,正式營運則會申請專用帳號),要開放行事曆供程式存取,使用者必須授與該帳號讀取權限,授權完成可使用 Outlook 檢查是否看到測試對象的約會做為驗證。但有一點要留意,除了授權讀取空閒/忙碌時間、主旨、地點外,其他區域有個「可看到資料夾」一定要勾選。未勾選時 Oulook 可查看共享行事曆,但 EWS Managed API 不行,我花了不少時間才發現這個眉角。

若要求省事,也可請共用行事曆的使用者直接選取「權限等級:檢閱者」;若使用者很介意約會細節外流,只想透露主旨、地點,甚至只打算開放/空閒忙碌資訊,只勾選自己想開放範圍也成,但記得一定要勾選「可看到資料夾」,不然程式沒戲唱:

程式範例如下。查詢他人行事曆時,有個關鍵是使用 new FolderId(WellKnownFloderName.Calendar, "對方的Email") 取得資料夾代號,若對方未授與「可看到資料夾」權限,程式會在 FindAppointments 時噴出找不到資料夾的錯誤。

private static void QuerySharedCalender()
{
    var ewsUrl = "https://the-exchange-server/ews/Exchange.asmx";
    ExchangeService ews = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
    ews.Credentials = new WebCredentials(userId, pwd, domainName);
    ews.Url = new Uri(ewsUrl);
    FolderId folderToAccess = 
            new FolderId(WellKnownFolderName.Calendar, "someone@company.com");
    //指定日期區間與資料筆數
    var view = new CalendarView(
        new DateTime(2017, 12, 10),
        new DateTime(2017, 12, 17), 
        1024);
    view.PropertySet = new PropertySet(
                AppointmentSchema.Subject, 
                AppointmentSchema.Start, 
                AppointmentSchema.End);
    FindItemsResults<Appointment> apps = ews.FindAppointments(folderToAccess, view);
    foreach (var app in apps)
    {
        Console.WriteLine(
            $"{app.Start:MM-dd HH:mm} - {app.End:MM-dd HH:mm} {app.Subject}");
    }
}

假設行事曆如下:

測試成功!

歡迎推文分享:
Published 16 December 2017 10:12 AM 由 Jeffrey
Filed under: ,
Views: 4,225



意見

沒有意見

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<December 2017>
SunMonTueWedThuFriSat
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456
 
RSS
創用 CC 授權條款
【廣告】
twMVC

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication