SharePoint 2010 ワークフロー アクションのサンドボックス配置


※ SharePoint 2013 以降では、サンボボックス ソリューションは非推奨です。SharePoint アドイン (SharePoint Add-ins) による開発手法を使用してください。

環境 :
SharePoint Server 2010
Visual Studio 2010
SharePoint Designer 2010

裏 10 行でズバリ ! サンドボックス ソリューション 

本シリーズは、「10 行でズバリ ! SharePoint 2010 開発」を理解された開発者向けに、さらに踏み込んだ内容を記載しています。(ちなみに、10 行にはおさまっていません。。。)

こんにちは。

今回は、SharePoint 2010 を使用して、SharePoint Designer で使用可能なカスタムのワークフローアクション (Workflow Action) をサンドボックス (Sandboxed) 配置する方法について説明します。

サンドボックス配置については、既にセミナー等でもよく紹介されていますが、 この配置方法を使用すると、利用部門 (エンドユーザー部門) からコードを含んだソリューションの (リモートからの) 配置が可能です。特に、SharePoint Online (BPOS) におけるシナリオにおいて開発コンポーネントをインストールするための強力な手段となります。
つまり、SharePoint Server 2010 になると、SharePoint Online では、Web パーツだけではなく、ここでご紹介するようなコードを含んだワークフローのカスタムアクションもサーバー上に配置できます。

注意 : ただし、セミナーでもお伝えしているように、サンドボックス ソリューションにはいくつかの制限があります。例えば、外部との接続はできないため、外部リスト (BCS) を経由し接続や、カスタムの Full Trust Proxy を使用する必要があります。

ソリューションの作成 (開発)

では、早速作成していきましょう。

まず、Visual Studio 2010 で、[空の SharePoint プロジェクト] を新規作成します。作成時に、下図の通り、サンドボックス (Sandboxed) ソリューションを選択します。

SharePiint Designer で使用されるカスタムアクションは WF のアクティビティ (Activity クラスから継承されたクラス) であり、通常は、アクティビティ ライブラリとして実装します。(以前のポスト 「Visual Studio で作成したカスタムアクションを SharePoint Designer で使用する方法」 を参照してください。SharePoint 2010 では、フィーチャーとして展開することも可能です。)
しかし、ここでご紹介するユーザーコード配置 (サンドボックス配置) によるワークフローアクションでは、クラス内のメソッドを実装して登録すれば良く、フレームワークが、このメソッドを呼び出してくれます。

このため、上記で作成したプロジェクトで、ソリューションエクスプローラのプロジェクト名を右クリックし、[追加] - [新しい項目] で [クラス] を追加します。(今回、作成するファイル名を MyCustomActoins.cs とします)

以下のメソッド (ChangeListName) を実装します。(このメソッドが、カスタムアクションとして実行されるメソッドになります。) ここでは、リストの GUID (ListId) を取得して、そのリストのタイトルを変更するというアクションです。
以下のように、入力引数は関数の引数そのものになりますが、第 1 引数に SPUserCodeWorkflowContext 型の引数を受け取ります。この引数を使用して、下記のようにサイト URL などの基本情報を取得することができます。

. . .

using System.Collections;
using Microsoft.SharePoint;
using Microsoft.SharePoint.UserCode;

namespace MyUserCodeWorkflowAction
{
  class MyCustomActoins
  {
    public Hashtable ChangeListName(
      SPUserCodeWorkflowContext context,
      string ListId,
      string NewTitle)
    {
      using (SPSite site = new SPSite(context.SiteUrl))
      {
        using (SPWeb web = site.OpenWeb(context.WebUrl))
        {
          SPList list = web.Lists[new Guid(ListId)];
          list.Title = NewTitle;
          list.Update();
        }
      }
      Hashtable ht = new Hashtable();
      ht.Add("success", true);
      ht.Add("ReturnValueTest", "this is test.");
      return ht;
    }
  }
}

上記では、処理結果として出力用の変数 (ReturnValueTest) も設定しています。

処理は、こうしたメソッドの準備だけで完了です。
あとは、このメソッドをフィーチャーとして配置できるようにします。ソリューションエクスプローラでプロジェクトを右クリックし、[追加] - [新しい項目] で [SharePoint] - [2010] の [空の要素] (下図) を追加します。

追加された Elements.xml (要素マニフェスト) に、以下の通り記述します。

下記で、$SharePoint.Project.AssemblyFullName$ には、

MyUserCodeWorkflowAction, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f49c953f13376bf5

など、このアセンブリの厳密名が挿入されます。(このため、このアセンブリの厳密名を調べて、そのまま挿入しても OK です。)

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <WorkflowActions>
    <Action Name="リスト名を勝手に変更する"
      SandboxedFunction="true"
      Assembly="$SharePoint.Project.AssemblyFullName$"
      ClassName="MyUserCodeWorkflowAction.MyCustomActoins"
      FunctionName="ChangeListName"
      AppliesTo="all"
      Category="Contoso 社カスタム動作">
      <RuleDesigner Sentence="リスト %1 を %2 に変更する (返された文字列は %3)">
        <FieldBind Field="ListId" Text="変更するリスト名" Id="1" DesignerType="ListNames" />
        <FieldBind Field="NewTitle" Text="変更後のタイトル" Id="2" DesignerType="TextBox" />
        <FieldBind Field="ReturnValueTest" Text="返り値" Id="3" DesignerType="ParameterNames" />
      </RuleDesigner>
      <Parameters>
        <Parameter Name="__Context"
          Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext, Microsoft.SharePoint.WorkflowActions"
          Direction="In" DesignerType="Hide" />
        <Parameter Name="ListId"
          Type="System.String, mscorlib"
          Direction="In"
          DesignerType="ListNames" />
        <Parameter Name="NewTitle"
          Type="System.String, mscorlib"
          Direction="In"
          DesignerType="TextBox" />
        <Parameter Name="ReturnValueTest"
          Type="System.String, mscorlib"
          Direction="Out"
          DesignerType="ParameterNames" />
      </Parameters>
    </Action>
  </WorkflowActions>
</Elements>

これまで、SharePoint Designer 用にカスタムのワークフローアクションを作成したことがある方はお気づきと思いますが (こちらのブログこちらの書籍 で紹介されています)、上記の記述方法は、実はこれまでの .actions ファイルの記述方法とほどんど同じです。(なお、上記の <Action /> の属性として UsesCurrentItem="true" を設定すると、リスト ワークフローにおいて、カレントのリストやリスト アイテムも取得できます。)

例えば、上記の通り、ListId の DesignerType として "ListNames" を設定すると、リストの Guid を手入力しなくても、サイト内のリスト名の一覧から選択できるような UI を SharePoint Designer が自動的に用意してくれます。(People Picker を使用した設定なども、同様に、DesignerType で設定できます。)
.actions ファイルの書式を調べたい方は、SharePoint ハイブ下の wss.actions ファイルを参考にしてください。(ここに、標準アクションのさまざまな設定がおこなわれています。)

しかし、今回のワークフローアクション (サンドボックス配置されるワークフローアクション) 専用に、いくつか独自な設定もおこなわれているので注意してください。
まず、上記で、SandboxedFunction="true" としている点に注意してください。この指定により、サンドボックス配置された、関数呼び出し型のアクションであることを示唆しています。
また、そのあとの FunctionName=... も必要です。この箇所で、どのアセンブリ (Assembly) の、どのクラス (ClassName) の、どの関数 (FunctionName) を使用するかを指定しています。

さいごに、このフィーチャーのスコープを「サイト」(Site) に設定します。
作成されたフィーチャーフォルダー (Feature1) を右クリックして [デザイナーの表示] メニューを選択し、表示される画面 (下図) で、スコープを「サイト」(Site) に変更しておきます。

以上で、すべて完了です。

リビルドをおこなって、プロジェクトを右クリックして [パッケージ] を選択して、パッケージ化 (つまり、.wsp ファイルの作成) をおこなってください。

動作確認

では、実際にサンドボックス (Sandboxed) 配置をおこなって動作を確認してみましょう。

SharePoint 2010 のサイトを表示し、[サイトの操作] - [サイトの設定] を選択して、表示される画面で [ソリューション] をクリックすると、ソリューションギャラリー (下図) が表示されます。

リボンの [ソリューション] タブの [ソリューションのアップロード] ボタンをクリックして、表示される画面で、上記で作成された .wsp ファイル (MyUserCodeWorkflowAction.wsp) を選択して、[アクティブ化] ボタンをクリックします。
これで、カスタムのサンドボックス ソリューションが配置されました。

SharePoint Designer を開いてみましょう。
ワークフローを新規作成すると、アクションとして、上記で配置されたカスタムアクションが表示されているはずです。

上図で [リスト名を勝手に変更する] を選択すると、下図の通り、デザイナー上に表示され、リスト名の選択と、タイトルの設定をおこなって、このワークフローを実行すると、そのリストのタイトルが変更されます。

なお、ユーザーコードのデバッグをおこなうには、F5 によるデバッグか、Visual Studio の [デバッグ] - [プロセスにアタッチ] メニューで、SPUCWorkerProcess.exe にアタッチしてください。

注意事項

このサンドボックス用のワークフロー アクション (アクティビティ) は、上記の通り、単なるメソッドの実装であり、ユーザー コード用の WF の仮想のアクティビティがこのメソッドを呼び出すというメカニズムによって、サンドボックスを超えた危険な処理を呼び出せないようにラッピングされています。このため、例えば、親のアクティビティを取得する、ワークフロー ランタイム用のメソッドを呼び出す (GetService メソッドなど) といった処理は実行できないため注意してください。(上記の SPUserCodeWorkflowContext クラスも、 ActivityExecutionContext クラスの派生クラスではありません。完全に、周りから隔離された世界です。)

 

Comments (0)

Skip to main content