ページ

2011年1月25日

MS ExchangeのメールボックスのカレンダーのIDをAPIで取得する

MS大好きなんですが、周りの人にはそのことが理解してもらえず、つくづく日本人にとっては愛情表現は難しいな、と思う今日この頃です。MSラブということで、MS Exchangeでのお仕事が来ましたが、そのときのメモです。今回はMS Exchangeで指定したユーザのメールボックスのカレンダーIDを取得するという、お題です。言語はもちろんC#です。そうです。C++++ですね。

MS ExchangeをAPIで操作するにはいくつか方法があります。Exchange 2000以降はCOM APIが用意されています。Exchange 2007 SP1以降はCOM APIに加えてEWSというSoapベースの仕組みが用意されています。EWSは直接SOAPをさわることもできますが、ライブラリにもなっているので、より簡便にあつかえます。ただし、この二つの仕組みでは指定したユーザのメールボックスのカレンダーのIDは取得できそうにありません。

ややこしいことにExchangeはもうひとつ、SoapベースのAPIを用意しています。Visual C#でWeb参照でhttps://${servername}/ews/Services.wsdlを指定すると利用できるようになります。Visual Studio素敵です。

まずは、初期化コードです。

ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;

ExchangeServiceBinding esb = new ExchangeServiceBinding();
esb.Url = @"https://サーバ名/EWS/Exchange.asmx";
esb.Credentials = new NetworkCredential("ログインID", "パスワード");
esb.RequestServerVersionValue = new RequestServerVersion();
esb.RequestServerVersionValue.Version = ExchangeVersionType.Exchange2007_SP1;
最初のServicePointManagerはサーバにちゃんとしたSSL証明書をもっていないので、証明書の検証をスキップしています。esbのオブジェクトを作った後は、適当なユーザでログインします。サーバのバージョンを指定しないと、のちのちの作業で悲しいことになるので、指定します。これで初期化は終了。

それでは実際のIDを取得します。コードはこんな感じ。
private String GetCalendarId(ExchangeServiceBinding esb, String mail) {
 FindFolderType fit = new FindFolderType();
 fit.FolderShape = new FolderResponseShapeType { BaseShape = DefaultShapeNamesType.AllProperties };
 fit.ParentFolderIds = new DistinguishedFolderIdType[] {
     new DistinguishedFolderIdType {
         Mailbox = new EmailAddressType{ EmailAddress=mail},
         Id = DistinguishedFolderIdNameType.msgfolderroot
     }
 };
 fit.Traversal = FolderQueryTraversalType.Shallow;
 FindFolderResponseType firt = esb.FindFolder(fit);
 FindFolderResponseMessageType firmt = (FindFolderResponseMessageType)firt.ResponseMessages.Items[0];
 foreach (BaseFolderType ft in firmt.RootFolder.Folders) {
     if (ft.FolderClass != null) {
         String fts = ft.FolderClass.ToString();
         if (ft.FolderClass.ToString().Equals("IPF.Appointment")) {
             String fid = ft.FolderId.Id;
             return fid;
         }
     }
 }
     
 return null;
}

エラー処理はちょっとサボっています。フォルダのタイプを見分ける仕組みはFolderClassの名前を使いましたが、別のタイプのフォルダを取得する場合はFolderClass名がかぶることもあるので、別のフィールド値(?)を使わないといけません。まあ、実際に動かせば何とかなりそうですね。これで、EwsIDという形のIDが取得できます。Exchangeのややこしいところは、IDはいろいろ種類があって、EwsLegacyIDとか、OwsIDとか、それ以外にも数種類あります。
ややこしや~。

でわでわ

0 件のコメント: