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 では異なるネーミングルールとなっているようです。