[T2-401 デモ (4)] Custom の SharePoint Workflow Editor


環境 :
Visual Studio 2008 (.NET Framework 3.5)
SharePoint Server 2007

こんにちは。

  1. WCF の Transport レベルの Custom Channel Sample
  2. Rehosting を使ったエンドユーザへのワークフロー公開
  3. WF による Rule Base のアプリケーション
  4. Custom の SharePoint Workflow Editor

製品開発者向けということで実施した Tech Ed の T2-401 セッションですが、お約束通り、デモを添付しておきます。

ここまでの内容を元に、これを SharePoint に応用した、さいごにお見せしたサンプルです。(ライセンスの問題もお約束通り修正しておきました . . .)

download sample (20080826_SampleSPWorkflowCreator)

セッションの中で 1 つ言い忘れてしまったのですが、xoml の作成部分については、これまでの説明とまったく同様、普通にワークフローを構築して、いつものように WorkflowMarkupSerializer にお任せで OK です。(その部分のコードは、ソースをじっくりとみておいてください。) 違っている点とすれば、SharePoint 用のアクティビティを使っているという点だけです。

配置方法ですが、セッションでご説明したように、製品向けなどで SharePoint のワークフローを配置する際は、stsadm による 「ワークフローテンプレート」ではなく、 SharePoint Designer が使用している「ワークフロー」のデプロイのほうがさまざまな点で優れていました。
SharePoint では、WorkflowRuntime を直接起動して操作することは禁止されおり、ここでのポイントは SharePoint がワークフロー構築のために用意している (主に SharePoint Designer で使用されている)、ValidateWorkflowMarkupAndCreateSupportObjects、AssociateWorkflowMarkup などのメソッドが使えることでした。(http://msdn.microsoft.com/en-us/library/bb417436.aspx)
このため、SharePoint 展開用の「どのタスクリストを使うの ?」、「どのワークフローフォルダに入れるの ?」、「どのリストに関連付けるの ?」などの設定情報を記載したワークフロー構成ファイル (.xoml.wfconfig.xml) が必要で、この作成もおこなう必要があったわけです。(ただ、この定義は非常にシンプルなものですので、サンプルコードのように、XmlDocument などを使って自作すれば OK です) 

あとは WorkflowMarkupSerializer などを使ってこれまでと同じように処理をおこなえば良いのですが、ご説明したように、SharePoint 固有の他のさまざまな課題もクリアしなければなりません。
例えば、ワークフローを関連付けるリストは、リストの表示名ではなく GUID が必要となります。また、列についても、表示名ではなく内部名が必要となります。また、ワークフローも、ただのドキュメントライブラリではなく、ご説明した ServerTemplate ID が 117 番のワークフロー用のフォルダに入れておく必要があります。つまり、このフォルダがない場合には、このフォルダを作るという作業も必要になるわけです。
(さらに、ここではサンプルを簡単にするためにワークフローフォームも使っていませんが、カスタムの初期化フォームや、タスクフォームが必要な場合には、こうしたフォームも aspx などで構築しておき、配置する必要もあります。)

コードでは、これら事前の処理を実施するため、リスト Web サービス (Lists.asmx) を使用した事前のやりとりをおこっています。またファイルの配置などは、WebRequest オブジェクトを使って WebDAV フォルダにアクセスしています。

さいごに、セッションの終わりでご説明した点ですが、時間が迫っていて簡単にしか説明できませんでしたので、ここはちゃんと記載しておきましょう。SharePoint Designer が作成した xoml ですが、セッションでお見せしたように、参照しているアクティビティのライブラリ名が、

Microsoft.SharePoint.WorkflowActions.dll, Version=12.0.0.0, Culture=neutral, PublicKeyToken=null

となっていました。
これは、SharePoint Designer が、リモートからも登録されているアクティビティの dll を扱ってワークフローの作成と配置ができるために必要な仕様で、Sharepoint Designer は %userprofile%AppDataRoamingMicrosoftSharePoint DesignerProxyAssemblyCache12.0.0.6219 の中に、サーバ上の dll と同じクラスやメソッドを持った dll の Proxy を内部で生成しています。このため、プロフェッショナル開発者が自作したカスタムの dll (SharePoint Designer のアクティビティ) なども、ちゃんと Proxy がキャッシュされ、リモートからも正しく動作するようになっています。(よって、公開キーまではコピーできませんので、PublicKeyToken を null にして配置する必要があります。)
では、この処理と同じことを皆さんの製品の中でも実施したくなるかもしれませんが、セッションでご紹介した FetchLegalWorkflowActions などの Web サービスのメソッドは、ご説明したように製品が内部で使用しているもので、一般の開発者に公開されたメソッドではありません。そこで上記のダウンロードサンプルでは、サーバ側の Microsoft.SharePoint.WorkflowActions.dll と同じクラスやメソッドを持つスタブ用のコードを作成し、これをワークフロー構築で使用するようにしています。(xoml 構築のためのクラスですので、内部処理は必要ありません。)
よって、WebPart の開発などでサーバ側で動作するモジュールの場合にはこうした面倒なスタブコードは必要ありませんし、リモートで処理されるワークフローであっても、初期化処理 (OnWorkflowActivated など) 以降はカスタムアクティビティだけで構成するようにしておけば、(初期化部分のみ xoml のテンプレートなどを用意しておき) Microsoft のライブラリを真似てスタブを構成しておく必要もありません。一般的には、こうした方法で開発するほうが望ましいでしょう。

以下にこのスタブコード以外の処理コードの部分を掲載しておきます。

public partial class Form1 :Form

{

    public Form1()

    {

        InitializeComponent();

    }

 

    ComboBox[] Conditions = new ComboBox[3];

    ComboBox[] Tasks = new ComboBox[3];

    TextBox[] MailAddresses = new TextBox[3];

    TextBox[] FieldNames = new TextBox[3];

    TextBox[] FieldValues = new TextBox[3];

    TextBox[] Approvers = new TextBox[3];

 

    XmlDocument xomlDoc;

    XmlDocument configDoc;

 

    private void Form1_Load(object sender, EventArgs e)

    {

        Tasks[0] = Task0;

        Tasks[1] = Task1;

        Tasks[2] = Task2;

 

        MailAddresses[0] = MailAddress0;

        MailAddresses[1] = MailAddress1;

        MailAddresses[2] = MailAddress2;

 

        FieldNames[0] = FieldName0;

        FieldNames[1] = FieldName1;

        FieldNames[2] = FieldName2;

 

        FieldValues[0] = FieldValue0;

        FieldValues[1] = FieldValue1;

        FieldValues[2] = FieldValue2;

    }

 

    private void ExecuteButton_Click(object sender, EventArgs e)

    {

        // Step 0 : Workflow Location などの設定

        Step_SetupObjects();

 

        // Step 1 : Workflow Config を作成

        Step_CreateWorkflowConfig();

 

        // Step 2 : XOML を作成

        Step_CreateXoml();

 

        // Step 3 : Upload !

        Step_UploadFiles();

 

        // Step 4 : ワークフローのコンパイル

        WebPartPagesSvc.WebPartPagesWebService sv = new WebPartPagesSvc.WebPartPagesWebService();

        sv.Url = string.Format("{0}/{1}", SiteLoc.Text.TrimEnd(new char[] { '/' }), "_vti_bin/WebPartPages.asmx");

        sv.UseDefaultCredentials = true;

        sv.Credentials = System.Net.CredentialCache.DefaultCredentials;

        sv.PreAuthenticate = true;

 

        sv.ValidateWorkflowMarkupAndCreateSupportObjects(xomlDoc.InnerXml, "", configDoc.InnerXml, "2");

        sv.AssociateWorkflowMarkup(string.Format("Workflows/{0}/{0}.xoml.wfconfig.xml", WorkflowName.Text), "V1.0");

 

Comments (5)

  1. こんにちは。 WCF の Transport レベルの Custom Channel Sample Rehosting を使ったエンドユーザへのワークフロー公開 WF による Rule Base のアプリケーション

  2. こんにちは。 WCF の Transport レベルの Custom Channel Sample Rehosting を使ったエンドユーザへのワークフロー公開 WF による Rule Base のアプリケーション

  3. こんにちは。 WCF の Transport レベルの Custom Channel Sample Rehosting を使ったエンドユーザへのワークフロー公開 WF による Rule Base のアプリケーション

  4. Mohammad says:

    hi thanks for the post it is great

    i have downloaded the sample and run it

    it works fine but when the code reaches WebPartPagesWebService.AssociateWorkflowMarkup

    it gives this error

    Exception of type ‘Microsoft.SharePoint.SoapServer.SoapServerException’ was thrown.

    and i search for more details inside the error and i get that the StackTrace is

      at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)

      at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)

      at WorkflowWebApplication.sharepointdev1.WebPartPagesWebService.AssociateWorkflowMarkup(String configUrl, String configVersion)

    so could anyone help me to know why this error is happening

Skip to main content