Dynamics CRM 2011 複数組織展開の Silverlight Web リソース開発

みなさん、こんにちは。

今回は Silverlight Web リソースを複数の組織で利用する際の手順を紹介します。
複数の組織で利用するためには、サーバーの URL や組織名など、環境によって異なる情報を
ハードコードできません。またアプリケーション内で利用するクラス名も一般的なものにすることが
好まれます。

シナリオ

‐ ソリューションの一部として Silverlight Web リソースを利用する。
‐ カスタムフィールドやカスタムエンティティに対する操作も含む。
‐ 同じカスタマイズをもつ複数の組織や環境が存在し、同じ Silverlight
 Web リソースを利用する。

Silverlight Web リソースでは事前バインドが必要なため、カスタムフィールドや
カスタムエンティティの情報を取得し、アプリケーション内に保持する必要があります。
この際、以下の手順でコードを一般化可能です。

手順

以下の手順で作業を行います。

Silverlight ソリューションの準備

1. Visual Studio 2010 を開きます。

2. 新しいプロジェクトを作成します。

3. .NET Framework 4 を選択し、Silverlight アプリケーションを作成します。

image

4. Silverlight をホストする Web サイトを作成します。(任意)

conceptual schema definition language (CSDL) の取得

ソリューションが作成できたら、次はメタデータ情報およびサービスコンテキストを
含む CSDL を取得します。これは開発に必要なメタデータを含む任意の組織から
取得してください。

1. Internet Explorer で Dynamics CRM 2011 に接続します。

2. 設定 | カスタマイズ | 開発者リソースをクリックします。

3. サービス エンドポイントの一覧より、CSDL のダウンロードをクリックします。

image

CSDL の参照と一般化

次にダウンロードした CSDL ファイルをソリューションに追加し、一般化します。

1. Visual Studio 2010 の Silverlight ソリューションに戻ります。

2. Silverlight プロジェクトの参照設定を右クリックして、「サービス参照の追加」 をクリックします。

3. ダウンロードした CSDL ファイルを参照します。

4. 適当な名前空間を指定して、OK をクリックします。ここでは ODataSample としました。
また、サービス名称が <組織名>Context になっていることを確認します。後ほどこの名称は
変更します。

image

5. ソリューションエクスプローラーで 「すべてのファイルを表示」 をクリックします。

image

6. 先ほど追加したサービス参照を展開し、Reference.cs を開きます。

image

7.  クラス名が <組織>Context になっていることを確認します。このままでも別に問題はありませんが、
一般的な名前に変更したい場合には、クラス名を右クリックし、リファクター | 名前の変更を選択します。

image

8. 任意の新しい名前を入れます。ここでは XrmContext にしました。

image

9. OK をクリックすると自動で名前が更新されます。

プロキシの作成

以上で準備が整いました。次に実際にプロキシを生成します。

1. MainPage.xaml を右クリックして、コードの表示をクリックします。

2. using を追加して、サービス参照と必要な参照を含めます。

using SilverlightApplication1.ODataSample;
using System.Windows.Browser;
using System.Data.Services.Client;

3. 以下のヘルパーメソッドを追加します。

private static ScriptObject GetContext()
{
    ScriptObject xrmProperty = (ScriptObject)HtmlPage.Window.GetProperty("Xrm");
    // Xrm オブジェクトが取得できない場合
    if (null == xrmProperty)
    {
        // グローバルコンテキストを取得 
        try
        {
            ScriptObject globalContext = (ScriptObject)HtmlPage.Window.Invoke("GetGlobalContext");
            return globalContext;
        }
        catch (System.InvalidOperationException)
        {
            throw new InvalidOperationException("Property \"Xrm\" is null and the Global Context is not available.");
        }
    }

    // Xrm.Page を取得
    ScriptObject pageProperty = (ScriptObject)xrmProperty.GetProperty("Page");
    if (null == pageProperty)
    {
        throw new InvalidOperationException("Property \"Xrm.Page\" is null");
    }

    // Xrm。Page.context を取得
    ScriptObject contextProperty = (ScriptObject)pageProperty.GetProperty("context");
    if (null == contextProperty)
    {
        throw new InvalidOperationException("Property \"Xrm.Page.context\" is null");
    }
    return contextProperty;
}

4. 以下のコードでプロキシを生成します。

XrmContext context;
System.String serverUrl;

// サーバー URL の取得と REST エンドポイント URL の作成
serverUrl = (String)GetContext().Invoke("getServerUrl");
if (serverUrl.EndsWith("/"))
    serverUrl = serverUrl.Substring(0, serverUrl.Length - 1);
Uri ODataUri = new Uri(serverUrl + "/xrmservices/2011/organizationdata.svc/", UriKind.Absolute);

// 取得した URL を渡してプロキシを生成
// IgnoreMissingProperties は True が必須
context = new XrmContext(ODataUri) { IgnoreMissingProperties = true };

5. 後は生成された XrmContext を利用してコードを記述します。

サービス参照に機能を追加

前回の記事で REST エンドポイントを利用した更新時に問題が発生する場合があることを
紹介しました。更新作業をこのアプリケーションで行う際は、そちらを参照して、機能追加
してください。

Dynamics CRM 2011 REST エンドポイントでレコード更新時に発生する問題
https://blogs.msdn.com/b/crmjapan/archive/2011/06/28/dynamics-crm-2011-issue-with-updating-records-via-rest-endpoint.aspx

まとめ

Silverlight は事前バインドが必須のため、カスタムフィールドやカスタムエンティティの
情報も開発時に保持している必要があります。ただし CSDL ファイルは特定の組織に
固有の情報ではないため、上記のような手順で一般化し、複数の組織に対して開発を
行うことが可能です。

参考:Silverlight Web リソースで REST エンドポイントを使用する
https://msdn.microsoft.com/ja-jp/library/gg309342

‐ Dynamics CRM サポート 中村 憲一郎