CRM Online では、 今のところ、北米かヨーロッパ、アジア太平洋のサーバーでホストされます。自分の使用している CRM サーバーがどの場所で動作しているかは、サーバー名のアドレスを見ればわかりますが、せっかくなので IDiscoveryService Web Service を使用して 自分のCRM Online がどこでホストされているかを調べるサンプルを掲載します。CRM Onlineのサーバー名と実際に動作しているロケーションについては以下のURLを参照してください。
Discover the URL for Your Organization with IDiscoveryService Web Service
http://technet.microsoft.com/en-us/library/gg328127.aspx
IDiscoveryService を使用してみたかったので、プログラムでDiscoveryService 経由で取得した組織情報を列挙するサンプルを掲載します。サンプルを実行するとわかるのですが、特定の組織情報を取得する場合に指定する組織のユニーク名は CRM Online と OnPremise の場合でネーミングが異なります。
1. IDiscoveryServiceを使用するサンプルプログラム
コンソールアプリケーションを作成します。[Dynamics CRM 2011]遅延バインディング(Late Binding) でCRM Webサービス に接続する で記載したように、参照の追加により、sdkのbinフォルダに格納されている、microsoft.crm.sdk.proxy.dll と microsoft.xrm.sdk.dll を追加します。同様に、System.ServiceModel.dll と System.Runtime.Serialization.dll を追加します。
プロジェクトのプロパティを開いて、ターゲットフレームワークを .NET Framework 4.0 にします。ここまでで準備は完了です。
CRM Online の IDiscoveryService に接続して、組織情報を列挙するサンプルソースを記載します。サンプルでは、CRM Online 用の3箇所のIDiscoveryService 用のアドレスすべてに対して、RetrieveOrganizationsRequest を使用して、組織情報を取得しています。
サンプルでは、単独の組織を取得するサンプルとして、内部でRetrieveOrganizationRequest を使用するDisplayOrganizationInfo メソッドも実装しています。注意点として、CRM Online の場合、RetrieveOrganizationRequest で使用する 組織のユニーク名は 組織IDのGUIDからハイフンを除いた文字列になっています。CRM Onlineのホスト名の先頭の組織名らしき文字列(UrlName)ではないので注意してください。OnPremiseの場合は、組織名と同じになります。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Xrm.Sdk.Client; using System.ServiceModel.Description; using Microsoft.Xrm.Sdk.Discovery; using System.ServiceModel.Security; namespace LateBindingSample03 { class Program { static string[] discoveryServiceUrls = new string[]{ "https://dev.crm.dynamics.com/XRMServices/2011/Discovery.svc" ,"https://dev.crm4.dynamics.com/XRMServices/2011/Discovery.svc" ,"https://dev.crm5.dynamics.com/XRMServices/2011/Discovery.svc"}; static void Main(string[] args) { // 北米、ヨーロッパ、アジア太平洋のDiscoveryService を検索して、 // 組織情報を検索する string uniquename = DisplayOrganizationsInfo(); // 組織のユニーク名を指定して組織情報を検索する DisplayOrganizationInfo(uniquename); //DisplayOrganizationsInfoForOnPremise(); Console.ReadLine(); } #region Online版のサンプル /// <summary> /// 組織のユニーク名(CrmOnlineのURLで先頭に付与される組織名らしきものではないので注意) /// CrmOnlineの場合、組織のGUIDにハイフンを除いた文字列 /// </summary> /// <param name="uniqueName"></param> public static void DisplayOrganizationInfo(string uniqueName) { if (string.IsNullOrEmpty(uniqueName)) return; foreach (var discoveryServiceUrl in discoveryServiceUrls) { try { using (DiscoveryServiceProxy service = GetDiscoveryService(discoveryServiceUrl)) { RetrieveOrganizationRequest request = new RetrieveOrganizationRequest() { UniqueName = uniqueName, Release = OrganizationRelease.Current, AccessType = EndpointAccessType.Default }; RetrieveOrganizationResponse response = service.Execute(request) as RetrieveOrganizationResponse; Console.WriteLine("取得できたDiscoveryServiceのURL:{0}", discoveryServiceUrl); OrganizationDetail detail = response.Detail; Console.WriteLine("組織GUID:{0}", detail.OrganizationId); Console.WriteLine("組織UniqueName:{0}", detail.UniqueName); Console.WriteLine("組織フレンドリ名:{0}", detail.FriendlyName); Console.WriteLine("組織名(UrlName):{0}", detail.UrlName); Console.WriteLine("バージョン:{0}", detail.OrganizationVersion); Console.WriteLine("エンドポイント一覧"); Console.WriteLine("WebApp:{0}", detail.Endpoints[EndpointType.WebApplication]); Console.WriteLine("組織サービス:{0}", detail.Endpoints[EndpointType.OrganizationService]); Console.WriteLine("組織データサービス:{0}", detail.Endpoints[EndpointType.OrganizationDataService]); } } catch (SecurityAccessDeniedException) { // 該当のエリアには指定した組織が存在しない } } } public static string DisplayOrganizationsInfo() { string uniquename = string.Empty; foreach (var discoveryServiceUrl in discoveryServiceUrls) { try { using (DiscoveryServiceProxy service = GetDiscoveryService(discoveryServiceUrl)) { RetrieveOrganizationsRequest request = new RetrieveOrganizationsRequest() { AccessType = EndpointAccessType.Default, Release = OrganizationRelease.Current }; RetrieveOrganizationsResponse response = service.Execute(request) as RetrieveOrganizationsResponse; foreach (OrganizationDetail detail in response.Details) { Console.WriteLine("組織GUID:{0}", detail.OrganizationId); Console.WriteLine("組織UniqueName:{0}", detail.UniqueName); Console.WriteLine("組織フレンドリ名:{0}", detail.FriendlyName); Console.WriteLine("組織名(UrlName):{0}", detail.UrlName); Console.WriteLine("バージョン:{0}", detail.OrganizationVersion); Console.WriteLine("エンドポイント一覧"); Console.WriteLine("WebApp:{0}", detail.Endpoints[EndpointType.WebApplication]); Console.WriteLine("組織サービス:{0}", detail.Endpoints[EndpointType.OrganizationService]); Console.WriteLine("組織データサービス:{0}", detail.Endpoints[EndpointType.OrganizationDataService]); uniquename = detail.UniqueName; } } } catch (SecurityAccessDeniedException) { // 該当のエリアには指定した組織が存在しない } } return uniquename; } private static DiscoveryServiceProxy GetDiscoveryService(string discoverServiceAddress) { // Windows Live のユーザ名とパスワード ClientCredentials liveCredential = new ClientCredentials(); liveCredential.UserName.UserName = "testxxx@xxxx.jp"; liveCredential.UserName.Password = "xxxaaaxxx"; // DeviceID ClientCredentials deviceCredential = new ClientCredentials(); deviceCredential.UserName.UserName = "xxxxxxddddddd"; deviceCredential.UserName.Password = "xsadfasfawsfas"; DiscoveryServiceProxy proxy = new DiscoveryServiceProxy(new Uri(discoverServiceAddress), null, liveCredential, deviceCredential); return proxy; } #endregion #region OnPremiseの場合のサンプル /// <summary> /// 参考としてOnPremise版の処理。Online 版と異なり、UniqueName と組織名は同じになります。 /// </summary> private static void DisplayOrganizationsInfoForOnPremise() { using (DiscoveryServiceProxy service = GetDiscoveryServiceForOnPremise()) { RetrieveOrganizationsRequest request = new RetrieveOrganizationsRequest() { AccessType = EndpointAccessType.Default, Release = OrganizationRelease.Current }; RetrieveOrganizationsResponse response = service.Execute(request) as RetrieveOrganizationsResponse; foreach (OrganizationDetail detail in response.Details) { Console.WriteLine("組織GUID:{0}", detail.OrganizationId); Console.WriteLine("組織UniqueName:{0}", detail.UniqueName); Console.WriteLine("組織フレンドリ名:{0}", detail.FriendlyName); Console.WriteLine("組織名(UrlName):{0}", detail.UrlName); Console.WriteLine("バージョン:{0}", detail.OrganizationVersion); Console.WriteLine("エンドポイント一覧"); Console.WriteLine("WebApp:{0}", detail.Endpoints[EndpointType.WebApplication]); Console.WriteLine("組織サービス:{0}", detail.Endpoints[EndpointType.OrganizationService]); Console.WriteLine("組織データサービス:{0}", detail.Endpoints[EndpointType.OrganizationDataService]); } } } /// <summary> /// 参考:OnPremiseの場合 /// </summary> /// <returns></returns> private static DiscoveryServiceProxy GetDiscoveryServiceForOnPremise() { string url = "http://crmsvr01/XRMServices/2011/Discovery.svc"; // 実行ユーザの資格情報を使用 ClientCredentials credential = new ClientCredentials(); DiscoveryServiceProxy proxy = new DiscoveryServiceProxy(new Uri(url), null, credential, null); return proxy; } #endregion } }
上記サンプルプログラムで使用している、DeviceIDとパスワードは、SDKにソースコードで付属している deviceregistration ツール を使用して調べることができます。
2.まとめ
説明は以上です。間違い、指摘点などあればご連絡ください。
組織のユニーク名は Online と OnPremise では異なるネーミングルールとなっているようです。
さんのコメント: さんのコメント: