SharePoint でリモート イベント レシーバーを使用する
リモート イベント レシーバーを使用して、SharePoint アドイン モデルのイベントを処理します。 AppInstalled および AppUninstalling イベントを使用すると、アドインに必要な SharePoint オブジェクトとその他のイベント レシーバーをセットアップまたは削除できます。
適用対象: SharePoint 用アドイン | SharePoint 2013 | SharePoint Online
重要 2017 年 1 月時点で、SharePoint Online は、"-ed" リモート イベント レシーバーの代わりに使用できるリスト Webhook をサポートしています。 Webhook の詳細については、「SharePoint Webhook の概要」を参照してください。 また、sp-dev-samples GitHub リポジトリからいくつかの Webhook サンプルを入手することもできます。
Core.EventReceivers サンプルでは、プロバイダー向けのホスト型アドインを使用してリモート イベント レシーバーで AppInstalled イベントおよび AppUninstalling イベントを処理する方法を紹介します。 AppInstalled イベントおよび AppUninstalling イベントでは、アドインが実行時に使用する SharePoint オブジェクトをセットアップおよび削除します。 さらに、AppInstalled イベント ハンドラーでは、ItemAdded イベント ハンドラーをリストに追加します。 このソリューションは、以下の操作を行うために使用してください。
- アドインの初めての実行時に AppInstalled イベントを使用して構成を行い、さまざまな SharePoint オブジェクトや、アドインで処理する追加のイベント レシーバーをセットアップします。
- 完全に信頼されたコード ソリューションを使用して実装したイベント レシーバーと置き換えます。 完全に信頼されたコード ソリューションでは、SharePoint サーバー上でイベント レシーバーを実行できます。 新しい SharePoint アドイン モデルでは、SharePoint サーバーでイベント レシーバーを実行できないため、Web サーバーにリモート イベント レシーバーを実装する必要があります。
- SharePoint で発生した変更の通知を受け取ります。 たとえば、新しいアイテムがリストに追加されたときタスクを実行する場合に利用できます。
- 変更ログのソリューションを補完します。 リモート イベント レシーバー パターンを変更ログ パターンと一緒に使用すると、SharePoint コンテンツ データベース、サイト コレクション、サイト、またリストに加えられたすべての変更を処理する、さらに信頼性の高いアーキテクチャが提供されます。 リモート イベント レシーバーは即座に実行されますが、リモート サーバー上で実行されているため、通信エラーが発生する可能性があります。 変更ログ パターンによりすべての変更が処理可能な状態に保持されますが、アプリケーションによる変更の処理は、通常、スケジュールに従って (たとえば、タイマー ジョブとして) 実行されます。 これは、変更が即座には処理されないことを意味します。 これら 2 つのパターンを一緒に使用すれば、同じ変更を 2 回処理する可能性を確実に回避するメカニズムを使用できます。 詳細については、「 ChangeQuery と ChangeToken で SharePoint の変更ログを照会する」を参照してください。
注:
SharePoint ホスト型アドインは、リモート イベント レシーバーをサポートしていません。 リモート イベント レシーバーを使用するには、プロバイダー向けのホスト型アドインを使用する必要があります。 リモート イベント レシーバーは、同期のシナリオや、長時間実行するプロセスのために使用するべきではありません。 詳細については、「 SharePoint 2013 でアドイン イベント レシーバーを作成する」を参照してください。
はじめに
まず、 Core.EventReceivers サンプル アドインを、GitHub の Office 365 Developer Patterns and Practices プロジェクトからダウンロードします。
このアドインを実行する前に、次の手順を実行します。
Core.EventReceivers プロジェクトのプロパティで、[ アプリのインストールと アプリの アンインストールの処理 ] が [True] に設定されていることを確認します。 [アプリのインストールの処理] と [アプリのアンインストールの処理] を True に設定すると、AppInstalled イベントと AppUninstalling イベントのイベント ハンドラーを定義する WCF サービスが作成されます。 Core.EventReceivers で、AppManifest.xml のショートカット メニューを開き (右クリック)、[プロパティ] を選択します。 InstalledEventEndpoint および UninstallingEventEndpoint は AppInstalled および AppUninstalling の各イベントを処理するリモート イベント レシーバーをポイントします。
リモート イベント レシーバーをホスト Web のオブジェクトにアタッチするには、通常、そのオブジェクトに対してのみ 管理 アクセス許可が必要です。 たとえば、イベント レシーバーを既存のリストにアタッチする場合、アドインにはその [リスト] に対してのみ [管理] アクセス許可が必要です。 このコード サンプルでは、リストを追加し、ホスト Web 上の機能をアクティブ化するため、 [Web] に対する [管理] アクセス許可が必要です。 Web に対して管理アクセス許可を設定するには、次のようにします。
Core.EventReceivers\AppManifest.xml をダブルクリックします。
[アクセス許可] を選択します。
[スコープ] が [Web] に設定され、[アクセス許可] が [管理] に設定されていることを確認します。
このコード例を実行するには、Azure サブスクリプションが必要です。 試用をサインアップするには、 1 か月間の無料評価版をご利用ください。
Azure Service Bus の名前空間を作成します。
「サービス バス名前空間を作成する」の手順を実行します。
プライマリ接続文字列を、作成したばかりのサービス バス名前空間からコピーします。
Visual Studio に戻ります。
[Core.EventReceivers >Properties>SharePoint] を右クリックします。
[Microsoft Azure Service Bus 経由でのデバッグを有効にする] を選択します。
接続文字列Microsoft Azure Service Busに接続文字列を貼り付けます。
保存] を選択します。
コード サンプルを実行し、次の追加の手順を実行します。
[アプリへのアクセス許可の付与] ウィンドウで [信頼] をクリックします。
[アプリへのアクセス許可の付与] ウィンドウを閉じます。
アドインと WCF サービスのインストールが完了すると、ブラウザーが開きます。
Office 365 サイトにサインインします。 Core.EventReceivers アドインのスタート ページが表示されます。
Core.EventReceivers アドインを使用する
Core.EventReceivers コード サンプルのデモを見るには、次の手順を実行します。
サンプルを実行し、スタート ページで [サイトに戻る] を選択します。
[サイト コンテンツ] を選択します。
[Remote Event Receiver Jobs] (リモート イベント レシーバーのジョブ) を選択します。
[新しいアイテム] を選択します。
[Title] (タイトル) に「Contoso」と入力し、[Description] (説明) に「Contoso test」と入力します。
リストに戻り、ページを更新します。
新しく追加されたアイテムの説明が「Contoso test Updated by ReR 192336」に更新されたことを確認します (192336 はタイムスタンプ)。
Services/AppEventReceiver.cs では、AppEventReceiver が IRemoteEventService インターフェイスを実装します。 このコード サンプルでは、同期イベントを使用するため、ProcessEvent メソッドの実装を提供しています。 非同期イベントを使用する場合は、 ProcessOneWayEvent メソッドの実装を提供する必要があります。
ProcessEvent は、次の SPRemoteEventType リモート イベントを処理します。
アドインをインストールするときの AppInstalled イベント。 AppInstalled イベントが発生すると、 ProcessEvent は HandleAppInstalled を呼び出します。
アドインを アンインストールするときのイベントのアンインストール。 AppUninstalling イベントが発生すると、ProcessEvent は HandleAppUninstalling を呼び出します。 AppUninstalling イベントは、サイトのごみ箱からアドインを削除するか (エンド ユーザーの場合)、またはテストリストのアプリ (開発者向け) からアドインを削除することによって、ユーザーがアドインを完全に削除した場合にのみ実行されます。
リストにアイテムが追加された時の ItemAdded イベント。 ItemAdded イベントが発生すると、 ProcessEvent は HandleItemAdded を呼び出します。
注:
Core.EventReceiver プロジェクトのプロパティでは、[ アプリのインストールを処理する] プロパティと [ アプリのアンインストールの処理 ] プロパティのみを使用できます。 このコード サンプルでは、アドインのインストール中に AppInstalled イベントを使用してホスト Web 上のリストに ItemAdded イベント ハンドラーを追加する方法を示しています。
注:
この記事で提供されるコードは、明示または黙示のいかなる種類の保証なしに現状のまま提供されるものであり、特定目的への適合性、商品性、権利侵害の不存在についての暗黙的な保証は一切ありません。
public SPRemoteEventResult ProcessEvent(SPRemoteEventProperties properties)
{
SPRemoteEventResult result = new SPRemoteEventResult();
switch (properties.EventType)
{
case SPRemoteEventType.AppInstalled:
HandleAppInstalled(properties);
break;
case SPRemoteEventType.AppUninstalling:
HandleAppUninstalling(properties);
break;
case SPRemoteEventType.ItemAdded:
HandleItemAdded(properties);
break;
}
return result;
}
HandleAppInstalled は、RemoteEventReceiverManager.cs 内の RemoteEventReceiverManager.AssociateRemoteEventsToHostWeb を呼び出します。
private void HandleAppInstalled(SPRemoteEventProperties properties)
{
using (ClientContext clientContext =
TokenHelper.CreateAppEventClientContext(properties, false))
{
if (clientContext != null)
{
new RemoteEventReceiverManager().AssociateRemoteEventsToHostWeb(clientContext);
}
}
}
AssociateRemoteEventsToHostWeb は、Core.EventReceivers アドインが使用するさまざまな SharePoint オブジェクトを作成または有効にします。 要件によっては、異なる動作が必要になります。 AssociateRemoteEventsToHostWeb は次の処理を実行します。
Web.Features.Add を使用することにより、プッシュ通知機能を有効にします。
clientContext オブジェクトを使用してリストを検索します。 リストが存在しない場合は、CreateJobsList でリストを作成します。 リストが存在する場合は、 List.EventReceivers を使用して、 ItemAddedEvent という名前の既存のイベント レシーバーを検索します。
ItemAddedEvent イベント レシーバーが存在しない場合は、次の処理を実行します。
EventReceiverDefinitionCreationInformation オブジェクトの新しいインスタンスを作成して、新しいリモート イベント レシーバーを作成します。 ItemAdded イベント レシーバー タイプを EventReceiverDefinitionCreationInformation.EventType に追加します。
EventReceiverDefinitionCreationInformation.ReceiverURL に AppInstalled リモート イベント レシーバーの URL を設定します。
List.EventReceivers.Add を使用して、新しいイベント レシーバーをリストに追加します。
public void AssociateRemoteEventsToHostWeb(ClientContext clientContext)
{
// Add Push Notification feature to host web.
// Not required but it is included here to show you
// how to activate features.
clientContext.Web.Features.Add(
new Guid("41e1d4bf-b1a2-47f7-ab80-d5d6cbba3092"),
true, FeatureDefinitionScope.None);
// Get the Title and EventReceivers lists.
clientContext.Load(clientContext.Web.Lists,
lists => lists.Include(
list => list.Title,
list => list.EventReceivers).Where
(list => list.Title == LIST_TITLE));
clientContext.ExecuteQuery();
List jobsList = clientContext.Web.Lists.FirstOrDefault();
bool rerExists = false;
if (null == jobsList)
{
// List does not exist, create it.
jobsList = CreateJobsList(clientContext);
}
else
{
foreach (var rer in jobsList.EventReceivers)
{
if (rer.ReceiverName == RECEIVER_NAME)
{
rerExists = true;
System.Diagnostics.Trace.WriteLine("Found existing ItemAdded receiver at "
+ rer.ReceiverUrl);
}
}
}
if (!rerExists)
{
EventReceiverDefinitionCreationInformation receiver =
new EventReceiverDefinitionCreationInformation();
receiver.EventType = EventReceiverType.ItemAdded;
// Get WCF URL where this message was handled.
OperationContext op = OperationContext.Current;
Message msg = op.RequestContext.RequestMessage;
receiver.ReceiverUrl = msg.Headers.To.ToString();
receiver.ReceiverName = RECEIVER_NAME;
receiver.Synchronization = EventReceiverSynchronization.Synchronous;
// Add the new event receiver to a list in the host web.
jobsList.EventReceivers.Add(receiver);
clientContext.ExecuteQuery();
System.Diagnostics.Trace.WriteLine("Added ItemAdded receiver at " + receiver.ReceiverUrl);
}
}
アイテムが Remote Event Receiver Jobs リストに追加されると、AppEventReceiver.svc.cs 内の ProcessEvent が ItemAdded イベントを処理し、HandleItemAdded を呼び出します。 HandleItemAdded は、RemoteEventReceiverManager.ItemAddedToListEventHandler を呼び出します。 ItemAddedToListEventHandler は、追加されたリスト アイテムをフェッチし、リスト アイテムの説明に「 Updated by ReR」という文字列を追加します。
public void ItemAddedToListEventHandler(ClientContext clientContext, Guid listId, int listItemId)
{
try
{
List photos = clientContext.Web.Lists.GetById(listId);
ListItem item = photos.GetItemById(listItemId);
clientContext.Load(item);
clientContext.ExecuteQuery();
item["Description"] += "\nUpdated by RER " +
System.DateTime.Now.ToLongTimeString();
item.Update();
clientContext.ExecuteQuery();
}
catch (Exception oops)
{
System.Diagnostics.Trace.WriteLine(oops.Message);
}
}