今天實驗了一下使用EWS訪問exchange郵件,網上說的都很簡單,可我卻是碰到了N多問題啊,不過最終還是成功了,也不枉我加班了。把一些方法及遇到的問題記錄下來,希望對有類似exchange功能開發需求的人有所協助。
第一步是下載Exchange Web Services Managed API,這個DLL封裝了很多對EWS的訪問,比起直接使用EWS產生的代理類,那是方便多了,:
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=c3342fb3-fbcc-4127-becf-872c746840e1
使用EWS的程式碼範例網上有不少,微軟網站上也有,部落格園裡有兩篇關於這個的介紹(下篇未給出連結):
http://www.cnblogs.com/diaojia/archive/2010/10/19/1855839.html
代碼還是比較簡單的,在此我貼上我的測試代碼:
public class AccessInfo { public string UserName; public string Password; public string Domain; public string ServerUrl; public string Email; } class Program { static void Main(string[] args) { AccessInfo info = new AccessInfo() { UserName = "administrator", Password = "p@ssw0rd", Domain = "contoso.com", ServerUrl = "https://contoso-exchange.contoso.com/ews/Exchange.asmx Email = "administrator@contoso.com" }; ReadMail(info); Console.Read(); } static void ReadMail(AccessInfo Info) { //ExchangeService版本為2010 ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010); //參數是使用者名稱,密碼,域 service.Credentials = new WebCredentials(Info.UserName, Info.Password, Info.Domain); //給出Exchange Server的URL http://xxxxxxx service.Url = new Uri(Info.ServerUrl); //你自己的郵件地址 xxx@xxx.xxx //service.AutodiscoverUrl(Info.Email); //建立過濾器, 條件為郵件未讀. SearchFilter sf = new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false); //尋找Inbox,加入過濾器條件,結果10條 FindItemsResults<Item> findResults = null; try { findResults = service.FindItems(WellKnownFolderName.Inbox, sf, new ItemView(10)); } catch (Exception ex) { Console.WriteLine(ex.Message); } foreach (Item item in findResults.Items) { EmailMessage email = EmailMessage.Bind(service, item.Id); Console.WriteLine(email.Subject); } } }",
這段代碼是最終測試成功的代碼,下面列一下碰到過的問題。
1、在service.AutodiscoverUrl(Info.Email)處出現異常:AutodiscoverUrl could not be located
這個問題最終沒有得到根本解決,我只是簡單的把這一行注釋了,因為我想既然顯示的指定了service.Url,那也就沒必要autodiscover了;
2、在service.FindItems(WellKnownFolderName.Inbox, sf, new ItemView(10))處出現異常,提示Http404錯誤
這個問題鬱悶了很久,因為寫的URL明明是沒有錯的,在瀏覽器中都可以訪問,也可以使用它來組建代理程式類,後面將要放棄的時候,找到了跟我有同樣遭遇的人寫
的文章:http://www.cnblogs.com/Bear-Study-Hard/archive/2010/10/11/1847824.html。(又是部落格園),裡頭說到是因為EWS網站禁用了SSL的緣故。的確
我的EWS網站也是禁用了SSL的,我比較不喜歡在瀏覽器裡訪問時老提示認證無效的警告。於是乎把SSL加上了,同時把http改為https(一開始測試是寫的http)。
3、啟用了SSL,在FindItems的時候提示“未能為SSL/TLS安全通道建立信任關係”。
完了,認證的問題來了,我一直都不明白的東西,始終不清楚怎樣為IIS網站設定認證,以及用戶端安裝認證。google到了兩篇文章,一篇是win2003 IIS6的,
一篇是win2008 IIS7的:
win2003 IIS6:http://www.cnblogs.com/kimzeng/archive/2009/12/17/1626171.html
win2008 IIS7:http://blog.csdn.net/steel_ligang/archive/2009/09/25/4593102.aspx
在此我要鄙視一下MS,兩代產品之間老是搞顛覆性的操作方式。兩篇文章裡介紹了很多,但都同時缺少了關於怎樣提交所申請的認證,以及如何擷取到頒發的認證的
操作。下面簡單介紹一下:
提交申請的認證
在瀏覽器中開啟:http://contoso.com/certsrv/,其中contoso.com是CA伺服器機器名,也就是域控機器名,介面類似如所示:
點擊“申請一個認證”,然後選擇“進階認證申請”,然後再選擇“使用 base64 編碼的 CMC 或 PKCS #10 檔案提交 一個認證申請,或使用 base64 編碼的 PKCS #7 檔案續訂認證申請。”,最中開啟的頁面如所示:
在上面的文字框裡貼上產生的HASH碼文字檔裡的所有內容,然後點擊提交,認證申請動作才算完成。
之後開啟憑證授權單位,找到“掛起的申請”,然後在右邊的列表裡找到申請的認證,右擊——所有任務——頒發,就完成了。
新申請的認證可到認證管理首頁(http://contoso.com/certsrv/)裡選擇“查看掛起的認證申請的狀態”,在接下來的頁面裡有下載連結提供。
在此我要提醒一下,必須在安裝認證服務之前安裝IIS,否則就沒有WEB上的認證服務頁面。
回到第3點提到的問題,在折騰了很長時間之後,在我的IIS裡依然沒有成功的加上認證。後面找到了微軟的一篇文章:
http://support.microsoft.com/kb/981954/zh-cn
裡面提到了關鍵的一點:過程中建立一個自簽名或 $ self-issued 的根憑證。儘管這一句並不是出現在這篇文章裡所描述的解決辦法裡,然而卻提醒了我,可以為IIS
建立一個自簽名的認證,或許有用。IIS7中伺服器憑證管理介面中就有建立自我簽署憑證的功能,過程就不細說了。建立完成之後,記得更改EWS網站所綁定的認證為剛才所建立的認證。更改之後,請確保程式中指定的服務URL網域名稱與認證中的“頒發給”屬性一致。
最後一點要提醒的,不要隨便為EWS網站添加主機頭,那將可能會導致EWS無法啟動,除非你對WCF的設定檔很熟悉。