エクスポート (0) 印刷
すべて展開

Silverlight Web リソースで REST エンドポイントを使用する

Microsoft Silverlight を使用して Microsoft Dynamics CRM 2011 および Microsoft Dynamics CRM Online の REST エンドポイントを操作するときは、Silverlight 用 WCF Data Services クライアント ライブラリを使用します。このライブラリは、データの操作には同じ HTTP プロトコル要求を使用しますが、データを ATOM 形式で返し、そのデータをクライアント側でオブジェクトに変換します。

このトピックの内容

作業を開始する前に

REST エンドポイントを使用する Silverlight Web リソース用のコードを記述する前に、いくつかのプランニングと作業前の手順を実行する必要があります。

WCF Data Services クライアント データ サービス クラスの生成

最初の手順として、Windows Communication Foundation (WCF) Data Services クライアント データ サービス クラスを Silverlight の Visual Studio 2010 アプリケーション プロジェクトに生成する必要があります。これらのクラスを Microsoft Dynamics CRM 用に生成する手順は、他のドキュメントで説明されている手順とは異なります。ここで作成しようとしているのは、Silverlight ソリューションへの組み込みと、任意の組織やさまざまな展開へのインストールが可能な Microsoft Dynamics CRM Web リソースであるからです。Silverlight Web リソースは、アプリケーションに組み込まれるため、認証について検討する必要はありません。

noteメモ
これらのクラスは、概念スキーマ定義言語 (CDSL) に基づいて生成されます。この CDSL は、REST エンドポイントが開発組織で使用可能なエンティティに基づいて生成します。クラスの生成時に存在するそのようなエンティティのみ、Silverlight アプリケーションで使用できます。

アプリケーションの開発中にエンティティや属性を追加または編集する場合は、WCF Data Services クライアント データ サービス クラスを再生成する必要があります。

WCF Data Services クライアント データ サービス クラスの生成

  1. Microsoft Dynamics CRM 2011 で、[設定] にナビゲートします。[カスタマイズ] を選択し、[開発者リソース] を選択します。

  2. [サービス エンドポイント] で、[CSDL のダウンロード] リンクをクリックして、OrganizationData.csdl ファイルをコンピューターに保存します。

  3. Visual Studio 2010 Silverlight アプリケーション プロジェクトで、[参照設定] を右クリックし、[サービス参照の追加] をクリックします。

  4. 手順 2 で OrganizationData.csdl ファイルを保存した場所のパスを入力し、[移動] をクリックします。

  5. [名前空間] に適切な名前を入力し、[OK] をクリックします。

入力した名前空間名とサービス参照がプロジェクトに表示されます。

Tipヒント
既定では、Visual Studio 2010 でプロジェクト用に作成された DataServiceContext オブジェクトの名前は「[展開環境の組織名]Context」となります。たとえば、ContosoDevOrg03 という名前の組織を使用しているときは、DataServiceContext という名前の ContosoDevOrg03Context オブジェクトが作成されます。

コンテキスト クラスの名前は、同じカスタマイズを含む他の組織のコードの動作に影響しません。ただし、次の手順を使用すると、このクラスの名前を変更して、特定の組織の参照を削除できます。

生成された DataServiceContext の名前を変更する

  1. Visual Studio 2010 で、ソリューション エクスプローラー ウィンドウ上部の [すべてのファイルを表示] というアイコンをクリックします。

  2. ソリューション エクスプローラーで、作成したサービス参照と Reference.datasvcmap ファイルを展開して、Reference.cs ファイルを表示します。

  3. Reference.cs ファイルを開いて、クラス定義を探します。

  4. そのクラスを右クリックして、[リファクター] を選択します。次に、[名前の変更] を選択します。

  5. プロジェクトをビルドします。

noteメモ
サービス参照を更新する場合は、この手順を繰り返す必要があります。

データ サービス コンテキスト拡張機能の実装

Important重要
WCF Data Services クライアント データ サービス クラスでは、レコードの更新時に不適切な動作が発生することがあります。たとえば、レコードのプロパティが変更されているかどうかにかかわらず、プロパティがすべて更新されます。また、エンティティが取得されるのではなくインスタンス化される場合、コード内に設定されていないプロパティはすべて null になります。レコードの既存の値は、これらの null 値に上書きされます。こうした問題を回避するには、次の手順を実行します。

データ サービス コンテキスト拡張機能の追加する

  1. System.Xml.Linq の参照を Microsoft Silverlight プロジェクトに追加します。

  2. 次のコードを使用して、プロジェクトに新しいクラス ファイルを作成します。

    
    using System;
    using System.Linq;
    using System.Data.Services.Client;
    using System.Reflection;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Collections.ObjectModel;
    using System.Xml.Linq;
    
    namespace Microsoft.Crm.Sdk.Samples.CrmODataService
    {
     partial class AdventureWorksCycleContext
    	{
    		#region Methods
    		partial void OnContextCreated()
    		{
    			this.ReadingEntity += this.OnReadingEntity;
    			this.WritingEntity += this.OnWritingEntity;
    		}
    		#endregion
    
    		#region Event Handlers
    		private void OnReadingEntity(object sender, ReadingWritingEntityEventArgs e)
    		{
    			ODataEntity entity = e.Entity as ODataEntity;
    			if (null == entity)
    			{
    				return;
    			}
    
    			entity.ClearChangedProperties();
    		}
    
    		private void OnWritingEntity(object sender, ReadingWritingEntityEventArgs e)
    		{
    			ODataEntity entity = e.Entity as ODataEntity;
    			if (null == entity)
    			{
    				return;
    			}
    
    			entity.RemoveUnchangedProperties(e.Data);
       entity.ClearChangedProperties();
    		}
    		#endregion
    	}
    
    	public abstract class ODataEntity
    	{
    		private readonly Collection<string> ChangedProperties = new Collection<string>();
    
    		public ODataEntity()
    		{
    			EventInfo info = this.GetType().GetEvent("PropertyChanged");
    			if (null != info)
    			{
    				PropertyChangedEventHandler method = new PropertyChangedEventHandler(this.OnEntityPropertyChanged);
    
    				//Ensure that the method is not attached and reattach it
    				info.RemoveEventHandler(this, method);
    				info.AddEventHandler(this, method);
    			}
    		}
    
    		#region Methods
    		public void ClearChangedProperties()
    		{
    			this.ChangedProperties.Clear();
    		}
    
    		internal void RemoveUnchangedProperties(XElement element)
    		{
    			const string AtomNamespace = "http://www.w3.org/2005/Atom";
    			const string DataServicesNamespace = "http://schemas.microsoft.com/ado/2007/08/dataservices";
    			const string DataServicesMetadataNamespace = DataServicesNamespace + "/metadata";
    
    			if (null == element)
    			{
    				throw new ArgumentNullException("element");
    			}
    
    			List<XElement> properties = (from c in element.Elements(XName.Get("content", AtomNamespace)
    												   ).Elements(XName.Get("properties", DataServicesMetadataNamespace)).Elements()
    										 select c).ToList();
    
    			foreach (XElement property in properties)
    			{
    				if (!this.ChangedProperties.Contains(property.Name.LocalName))
    				{
    					property.Remove();
    				}
    			}
    		}
    
    		private void OnEntityPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    		{
    			if (!this.ChangedProperties.Contains(e.PropertyName))
    			{
    				this.ChangedProperties.Add(e.PropertyName);
    			}
    		}
    		#endregion
    	}
    }
    
  3. ”Microsoft.Crm.Sdk.Samples.CrmODataService” 名前空間を、このプロジェクトのサービス参照名前空間で使用する名前空間に変更します。

  4. “AdventureWorksCycleContext” の Data Service Context クラスを、このプロジェクトで使用するクラスに変更します。

  5. サービス参照で、Reference.cs ファイルを編集します。": global::System.ComponentModel.INotifyPropertyChanged" の各インスタンスを ": ODataEntity, global::System.ComponentModel.INotifyPropertyChanged" に置き換えます。このテキストは組織のすべてのエンティティにあります。

    noteメモ
    Reference.cs ファイルが見つからない場合は、このトピックの前の「生成された DataServiceContext の名前を変更する」に記載される手順を参照してください。

ODataEntity.ClearChangedProperties メソッドの使用

エンティティを取得せずにエンティティをインスタンス化する場合は、ClearChangedProperties メソッドを使用して、変更されたプロパティの追跡内容を初期化する必要があります。たとえば、既存のレコードのプロパティ値がある場合は、エンティティ インスタンスを初期化してから値を設定できます。エンティティ インスタンスのプロパティを変更する前に、ClearChangedProperties を呼び出して、その時点で行われた変更のみをレコードの更新時にサーバーに送信する必要があります。

サーバーの URL の取得

作成したサービス参照を使用して、DataServiceContext クラスのインスタンスを作成するには、組織の REST エンドポイントへの URL を設定する必要があります。初期テストの場合は、一時的に静的な URL を使用してもかまいませんが、異なる組織にインストールする Silverlight Web リソースや、オフライン アクセス対応 Microsoft Office Outlook 用 Microsoft Dynamics CRM ユーザーがオフラインで作業しているときに作業する場合は、Xrm.Page.context.getServerUrl 関数または GetGlobalContext 関数 を使用して、組織コンテキストからサーバーの URL を取得する必要があります。

詳細については、「コンテキスト データへのアクセス」および「REST エンドポイントを使用した Microsoft Dynamics CRM データのクエリ」を参照してください。

REST エンドポイントで使用する Silverlight Web リソースの作成およびテスト

REST endpoint を認証するには、Silverlight アプリケーションを Microsoft Dynamics CRM アプリケーション内のページでホストする必要があります。コードのテストは、必ず、Silverlight Web リソースの作成後に行ってください。

詳細については、「Silverlight Web リソースの作成」およびアプリケーション ヘルプを参照してください。

HTML Web リソースを作成するときは、Silverlight で Microsoft Visual Studio 2010 アプリケーション プロジェクトによって生成された HTML ページを使用することをお勧めします。この HTML Web リソースを使用すると、Silverlight アプリケーションを Microsoft Dynamics CRM フォームのコンテンツ外でプレビューできます。詳細については、「サンプル: REST エンドポイントと Silverlight を使用した作成、取得、更新、および削除」の「sample_/CrmODataSilverlightTestPage.html」ページで、この HTML ページを Silverlight Web リソース用のホスト ページとして使用するために最低限必要な編集の例を参照してください。

Web リソースの名前と相対パス

HTML Web リソースでの ClientGlobalContext.js.aspx ページの参照は、Web リソースの名前に依存します。Web リソースの名前にバックスラッシュ文字を含める場合は、HTML ページでの参照に、これらの文字によって作成されるシミュレートされたフォルダー (contoso_/Pages/SilverlightHost/hostpage.htm など) を反映する必要があります。ClientGlobalContext.js.aspx ページの参照は、../../../ClientGlobalContext.js.aspx である必要があります。

同じことが、HTML ページ上の Silverlight ホスト オブジェクトのソース パラメーター参照にも当てはまります。HTML Web リソース名が contoso_/Pages/SilverlightHost/hostpage.htm で、ソース パラメーター値が ClientBin/MysilverlightApp.xap の場合、Silverlight Web リソースの名前は contoso_/Pages/SilverlightHost/ClientBin/MysilverlightApp.xap である必要があります。

Silverlight Web リソースをエンティティ フォームのコンテキストに表示するだけであれば、どのような名前でもかまいません。

Silverlight Web リソースのテスト

Silverlight Web リソースを記述、テスト、およびデバッグする方法については、「Silverlight Web リソースの記述およびテスト」および「Silverlight Web リソースのデバッグ」を参照してください。

コードの記述

事前のプランニングと作業前の手順が完了したら、DataServiceContext を使用して REST エンドポイントの操作を開始できます。

Silverlight 用 WCF Data Services クライアント ライブラリの使用

を次のサンプルに示します アプリケーション プロジェクトの MainPage.xaml.cs ファイル内で DataServiceContext のインスタンスを作成する方法Silverlight。このサンプルで使用するプロジェクト変数を次の表に示します。

 

プロジェクト変数 内容

Silverlight Application Namespace

DataServiceContextSample

既定で Visual Studio プロジェクトの名前に設定されます。

Service Reference Namespace

CrmODataService

サービス参照の作成時に入力されます。

Generated DataServiceContext

crmContext

既定で、コンテキストの生成に使用する CRM 組織の名前に設定されます。この例では "crmContext" です。


using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using DataServiceContextSample.CrmODataService;
using System.Data.Services.Client;
using System.Windows.Browser;


namespace DataServiceContextSample
{
 public partial class MainPage : UserControl
 {
  private crmContext context;
  private System.String serverUrl;

  public MainPage()
  {
   InitializeComponent();
   serverUrl = (String)GetContext().Invoke("getServerUrl");
   //Remove the trailing forward slash returned by CRM Online
   //So that it is always consistent with CRM On Premises
   if (serverUrl.EndsWith("/"))
    serverUrl = serverUrl.Substring(0, serverUrl.Length - 1);

   Uri ODataUri = new Uri(serverUrl + "/xrmservices/2011/organizationdata.svc/", UriKind.Absolute);
   context = new crmContext(ODataUri) { IgnoreMissingProperties = true };

  }
  /// <summary>
  /// Returns the application context object from the Xrm.Page if it is available 
  /// and by invoking the GetGlobalContext method if it is not.
  /// </summary>
  /// <returns></returns>
  private static ScriptObject GetContext()
  {
   ScriptObject xrmProperty = (ScriptObject)HtmlPage.Window.GetProperty("Xrm");
   if (null == xrmProperty)
   {
    //It may be that the global context should be used
    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.");
    }

   }

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

   ScriptObject contextProperty = (ScriptObject)pageProperty.GetProperty("context");
   if (null == contextProperty)
   {
    throw new InvalidOperationException("Property \"Xrm.Page.context\" is null");
   }

   return contextProperty;
  }
 }
}


詳細については、MSDN ドキュメント「WCF Data Services Client Library for Silverlight (Silverlight 用 WCF Data Services クライアント ライブラリ)」を参照してください。

Important重要
DataServiceContext のインスタンスを作成した後、DataServiceContext.IgnoreMissingProperties プロパティを true に設定する必要があります。

このプロパティを設定しないと、サービス参照の生成後に、Microsoft Dynamics CRM で新しいエンティティや属性を作成するときにエラーが発生します。

関連項目

Microsoft Dynamics CRM 2011 および Microsoft Dynamics CRM Online
このトピックについて Microsoft にコメントを送信する
© 2012 Microsoft Corporation. All rights reserved.

コミュニティの追加

表示:
© 2015 Microsoft