次の方法で共有


Project Server 2010 の PSI 拡張機能を作成する

適用対象: Office 2010 | Project 2010 | Project Server 2010 | SharePoint Server 2010

この記事の内容
簡単な "Hello World" サービスを作成する
PSI 拡張機能をインストールする
PSI 拡張機能をテストする
PSI 拡張機能を変更する
変更したサービスを展開およびテストする
PSI 拡張機能をデバッグする
Project Server 拡張機能の推奨ガイドライン

Microsoft Project Server 2010 の Project Server Interface (PSI) 拡張機能では、Windows Communication Foundation (WCF) を使用する必要があり、Project Web App によってアクセスされるサービスを作成する必要があります。サービス アクティブ化ファイルは、Project Web App のフロントエンド Web サーバー拡張機能にインストールされ、拡張機能は同じディレクトリ内の web.config ファイルによって構成されます (この記事は、Microsoft Corporation の Boaz Lev によるコンテンツを出典としています)。

この記事の手順では、次の作業を行う方法を示します。

  • HelloService という名前の簡単な PSI 拡張機能を作成します。

  • Project Web App にサービス アクティブ化ファイル (HelloService.svc) を作成し、Project Server の Web Server Extensions ディレクトリで web.config ファイルを変更して、拡張機能を展開します。

  • サービス参照を作成し、この簡単な拡張機能をテストします。

  • 拡張機能内の ResourceClient オブジェクトをプログラムで構成することによって、PSI の Resource サービスを呼び出すように拡張機能を変更します。

  • HelloService 拡張機能のメソッドから ResourceDataSet を返します。

  • App.config ファイルを使用して、テスト アプリケーションの HelloClient オブジェクトを構成します。

この記事は次のセクションで構成されます。

  • 簡単な "Hello World" サービスを作成する

  • PSI 拡張機能をインストールする

  • PSI 拡張機能をテストする

  • PSI 拡張機能を変更する

  • 変更したサービスを展開およびテストする

  • PSI 拡張機能をデバッグする

  • Project Server 拡張機能の推奨ガイドライン

Project 2010 SDK ダウンロードには、基本となる HelloService プロジェクト、および変更された HelloService2 プロジェクトの完全な Visual Studio ソリューションが含まれています。

前提条件

WCF ベースのアプリケーションを開発するには、Microsoft Visual Studio 2008 Service Pack 1 または Visual Studio 2010 が必要です。アプリケーションは Microsoft .NET Framework 3.5 をターゲットにする必要があります。この記事の手順では、Microsoft Visual C# を使用します。

PSI 拡張機能をより簡単にデバッグするには、Project Server 2010 のテスト インストールで開発を行ってください。

簡単な "Hello World" サービスを作成する

最も簡単な PSI 拡張機能には、1 つのメソッドのシグネチャを定義するインターフェイス クラスと、インターフェイスを実装するクラスが含まれます。新しい Visual Studio プロジェクトを開始するには、Windows グループのテンプレートのクラス ライブラリ テンプレートを使用するか、WCF サービス ライブラリ テンプレートを使用します。クラス ライブラリ テンプレートでは、参照と、メイン インターフェイスおよび実装クラスを追加する必要があります。WCF サービス ライブラリ テンプレートでは、テンプレートによって作成される App.config ファイルと一部のコードを削除できます。手順 1. では、Visual Studio 2010 で WCF サービス ライブラリ テンプレートを使用しています。

手順 1. 簡単な "Hello World" サービスを作成するには

  1. Visual Studio で、プロジェクトを作成します。[新しいプロジェクト] ダイアログ ボックスで、上部のドロップダウン リストの [.NET Framework 3.5] を選択します。[インストールされているテンプレート] ウィンドウで [WCF] をクリックし、[WCF サービス ライブラリ] をクリックします。この例では、プロジェクトに HelloService という名前を付けます。

    テンプレートによって HelloService プロジェクトが作成され、名前空間が HelloService に設定され、IService1.cs ファイルと Service1.cs ファイルが作成され、WCF の System.Runtime.Serialization および System.ServiceModel への参照が追加されます。

  2. テンプレートによって生成された App.config ファイルを削除します。PSI 拡張機能では App.config ファイルを使用しません。

  3. IService1.cs ファイルの名前を IHello.cs に変更し、IService1 へのすべての参照の名前を変更するためのダイアログ ボックスで [はい] をクリックします。Visual Studio によってインターフェイスの名前が IHello に変更されます。同様に、Service1.cs ファイルの名前を Hello.cs に変更します。Visual Studio によってクラスの名前が Hello に変更されます。このクラスは IHello インターフェイスを継承します。

  4. 手順 2. でサービス アクティブ化ファイルの機能を示すために、名前空間の名前を変更します。IHello.cs ファイルで HelloService 名前空間を選択し、名前空間を右クリックします。[リファクター] をクリックし、[名前の変更] をクリックします。たとえば、名前を Microsoft.SDK.Project.Samples.HelloService (または、その他の複数レベルの名前) に変更します。[OK] をクリックし、続いて表示されるダイアログ ボックスで [適用] をクリックして、[はい] をクリックします。

  5. HelloService プロジェクトの [プロパティ] ウィンドウを開き、[アプリケーション] タブをクリックします。[アセンブリ名] が HelloService、[既定の名前空間] が Microsoft.SDK.Project.Samples.HelloService、[対象のフレームワーク] が [.NET Framework 3.5] であることを確認します。

  6. HelloService プロジェクトの [プロパティ] ウィンドウの [署名] タブをクリックし、[アセンブリの署名] を選択します。厳密な名前のキー ファイルを作成します。たとえば、ファイルに Hello.snk という名前を付け、キー ファイルをパスワードで保護するためのチェック ボックスをオフにします。[OK] をクリックし、プロジェクトの [プロパティ] ウィンドウを閉じます。

  7. IHello.cs ファイルを開きます。Microsoft.SDK.Project.Samples.HelloService 名前空間の下のすべてのコードを次のコードで置き換えます。このコードは、サービス コントラクトの IHello インターフェイス、および操作のコントラクトの EchoHello メソッド シグネチャを定義します。

    {
        [ServiceContract]
        internal interface IHello
        {
            [OperationContract]
            string EchoHello();
        }
    }
    
  8. HelloService プロジェクトで、System.Web への参照を追加します。Hello.cs ファイルを開き、次の using ステートメントを追加します。

    using System.ServiceModel.Activation;
    using System.Web;
    

    System.ServiceModel.Activation 名前空間には、AspNetCompatibilityRequirements クラスが含まれます。PSI 拡張機能サービスは、ASP.NET と互換になるように設定する必要があります。詳細については、「AspNetCompatibilityRequirementsMode Enumeration」を参照してください。

    System.Web 名前空間には、HttpContext クラスが含まれます。このクラスからは、サービスの URL やその他の情報を取得できます。

    注意

    System.ServiceModel.Channels.OperationContext オブジェクトから WCF サービスのコンテキストを取得することもできます。ただし、OperationContext context = OperationContext.Current ステートメントでは、context.Channel.LocalAddress.Uri の値に、Project Web App インスタンス名があるアドレスの部分が含まれません。たとえば、サービス URL が https://ServerName/pwa/_vti_bin/PSI/HelloService.svc の場合、Uri の値は http://servername.domain.com/_vti_bin/PSI/HelloService.svc になります。SharePoint によって OperationContext オブジェクトのサービス URL が書き換えられます。

  9. Microsoft.SDK.Project.Samples.HelloService 名前空間の下のすべてのコードを次のコードで置き換えます。

    {
        [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
        internal class Hello : IHello
        {
            private static HttpContext context;
    
            public Hello()
            {
                context = HttpContext.Current;
            }
    
            public string EchoHello()
            {
                string serviceUrl = GetServiceUri().ToString();
    
                return "Hello from the WCF service:\n" + serviceUrl;
            }
    
            #region Helpers
    
            // Get the URI of the service activation file.
            static Uri GetServiceUri()
            {
                var requestUri = context.Request.Url;
    
                int portNum = 80;
                var portString = requestUrl.GetComponents(UriComponents.Port, UriFormat.SafeUnescaped);
    
                if (!string.IsNullOrEmpty(portString))
                {
                    portNum = int.Parse(portString);
                }    
                var uriBuilder = new UriBuilder(
                    requestUrl.GetComponents(UriComponents.Scheme, UriFormat.SafeUnescaped),
                    requestUrl.GetComponents(UriComponents.Host, UriFormat.SafeUnescaped),
                    portNum,
                    context.Request.RawUrl);
    
                return uriBuilder.Uri;
            }
    
            #endregion
        }
    }
    

    クラス アクセス修飾子を internal に変更し、同じアセンブリ内の他のクラス メソッドからのみメンバーにアクセスできるようにします。EchoHello メソッドは、IHello インターフェイスで定義されているのと同じシグネチャを持つ必要があります。

    context 変数を Hello クラス コンストラクターで初期化します。requestUri 変数を Uri 型として初期化します。

    requestUri の値を requestUri = context.Request.Url; ステートメントで設定すると、アドレス値に Project Web App インスタンスの名前が入りません。UriBuilder オブジェクトを作成することによって、サービスのホスト名と完全パスを挿入できます。たとえば、サービス URL が https://localhost/pwa/_vti_bin/PSI/HelloService.svc である場合、UriBuilder コンストラクターのパラメーターの値は次のようになります。

    • スキーム: http

    • ホスト: localhost

    • ポート: ポートの値が 80 の場合、URL には表示されません。

    • パスの値: RawUrl プロパティの値は /pwa/_vti_bin/PSI/HelloService.svc です。

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

PSI 拡張機能をインストールする

HelloService.dll アセンブリをインストールするには、グローバル アセンブリ キャッシュ (GAC) にアセンブリを追加し、サービス アクティブ化ファイルを作成し、Project Web App の web.config ファイルを変更する必要があります。

手順 2. "Hello World" サービスをインストールするには

  1. [Visual Studio コマンド プロンプト] ウィンドウを管理者として開き、手順 1. で作成した HelloService.dll アセンブリのディレクトリに移動します。

  2. GAC にアセンブリをインストールするには、次のコマンドを実行します。

    gacutil /if HelloService.dll
    
  3. PSI 拡張機能のサービス アクティブ化 (.svc) ファイルを作成します。[Program Files]\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI\PSI ディレクトリには、Project Server コンピューター上の Project Web App のすべてのインスタンスのフロントエンド サービス ファイルと web.config ファイルがあります。たとえば、テキスト エディターを使用して、次のような内容の HelloService.svc というファイルを作成します (service 属性はすべて 1 行で入力します)。

    <%@ServiceHost language="C#" 
        service="Microsoft.SDK.Project.Samples.HelloService.Hello, HelloService, 
        Version=1.0.0.0, Culture=neutral, PublicKeyToken=82a6a13f99b045eb" 
    %>
    

    service の各パラメーターが、次のように PSI 拡張機能の値と一致していることを確認してください。

    • Microsoft.SDK.Project.Samples.HelloService.Hello 値は、PSI 拡張機能の完全修飾クラス名です。

    • HelloService 値は、サービスのアセンブリの名前 (HelloService.dll) と一致している必要があります。

    • Version、Culture、および PublicKeyToken の値は、GAC のアセンブリの値と一致している必要があります。

      service のパラメーター値を変更するには

      1. エクスプローラーで Windows\assembly ディレクトリを開きます。たとえば、[スタート] メニューで [ファイル名を指定して実行] をクリックし、テキスト ボックスに「assembly」と入力して [OK] をクリックします。

      2. HelloService アセンブリ名を右クリックし、[プロパティ] をクリックします。

      3. [HelloService のプロパティ] ダイアログ ボックスで、[公開キー トークン] の値をコピーし、HelloService.svc ファイルの PublicKeyToken に値を貼り付けます。その他の値が異なる場合は、その値を対応する service のパラメーターにコピーします。

  4. テキスト エディターで Project Web App の web.config ファイルを開き、PSI 拡張機能の bindings 要素、behaviors 要素、および services 要素を追加します。各要素は、system.serviceModel 要素の子になります。

    web.config ファイルを変更するには

    1. PSI 拡張機能のバインド名とメタデータ交換 (MEX) エンドポイントのバインド名を含む basicHttpBinding を指定して、bindings 要素を追加します。これにより、クライアント アプリケーションを作成できるようになります。

          <bindings>
            <basicHttpBinding>
              <binding name="extensionBasicHttpConf"
                       closeTimeout="00:01:00"
                       openTimeout="00:01:00"
                       receiveTimeout="00:10:00"
                       sendTimeout="00:01:00"
                       allowCookies="true"
                       maxBufferSize="4194304"
                       maxReceivedMessageSize="500000000"
                       messageEncoding="Text"
                       transferMode="StreamedResponse">
                <security mode="TransportCredentialOnly">
                  <transport clientCredentialType="Ntlm" proxyCredentialType="Ntlm" realm="" />
                </security>
              </binding>
              <binding name="mexHttpBinding">
                <security mode="TransportCredentialOnly">
                  <transport clientCredentialType="Ntlm" proxyCredentialType="Ntlm" realm="" />
                </security>
              </binding>
            </basicHttpBinding>
          </bindings>
      

      clientCredentialType 属性の値と proxyCredentialType 属性の値は、Windows ではなく Ntlm にする必要があります。運用環境では、タイムアウトの値を小さくすることができます。

    2. サービスの開発中およびテスト中に発生する可能性があるエラーにサービスが例外の詳細を挿入できるように、behaviors 要素を追加します。運用環境では、serviceDebug 要素を false に設定できます。

          <behaviors>
            <serviceBehaviors>
              <behavior name="PSIExtensionServiceBehavior">
                <serviceDebug includeExceptionDetailInFaults="true" />
                <serviceMetadata httpGetEnabled="true" />
              </behavior>
            </serviceBehaviors>
          </behaviors>
      
    3. 各 PSI 拡張機能の service 子要素を含む services 要素を追加します。各 service 要素には、サービス コントラクトの endpoint および MEX コントラクトの endpoint が含まれます。

          <services>
            <service name="Microsoft.SDK.Project.Samples.HelloService.Hello"
                     behaviorConfiguration="PSIExtensionServiceBehavior">
              <endpoint address=""
                        binding="basicHttpBinding"
                        bindingConfiguration="extensionBasicHttpConf"
                        contract="Microsoft.SDK.Project.Samples.HelloService.IHello" />
              <endpoint address="mex"
                        binding="basicHttpBinding"
                        bindingConfiguration="mexHttpBinding"
                        name="mex"
                        contract="IMetadataExchange" />
            </service>
          </services>
      

      name 属性は、HelloWorld.svc アクティブ化ファイルと同様に、PSI 拡張機能クラスの完全修飾名と一致している必要があります。

      拡張機能サービスの address 属性は、空の文字列です。contract 属性には、完全修飾インターフェイス クラスを指定する必要があります。

    4. web.config ファイルを保存します。

  5. [Visual Studio コマンド プロンプト] ウィンドウで、iisreset を実行します。

PSI 拡張機能をテストする

Internet Explorer を使用して、サービス アクティブ化ファイルの URL をテストし、PSI 拡張機能が正しくインストールおよび構成されているかどうかを確認できます。テストが成功したら、拡張機能のメソッドを使用する簡単なテスト アプリケーションを作成します。

手順 3. "Hello World" サービスをテストするには

  1. Internet Explorer で、サービス アクティブ化ファイルの URL を入力します。たとえば、「https://localhost/pwa/_vti_bin/psi/helloservice.svc」のように入力します。PSI 拡張機能が正しくインストールされている場合は、図 1 に示すように、Internet Explorer に [Hello Service] タブが表示されます。

    図 1. Internet Explorer で PSI 拡張機能をテストする

    Internet Explorer での PSI 拡張機能のテスト

    Internet Explorer にエラーが表示された場合は、ソース コードと構成ファイルですべての名前空間のインスタンスと型名のスペルをチェックし、手順 2. を再度実行します。HelloService.dll アセンブリを再コンパイルする場合は、同じ gacutil コマンドを使用して GAC 内のアセンブリを上書きできます (gacutil /if HelloService.dll)。iisreset を再度実行し、Internet Explorer の表示を更新します。

  2. HelloService 拡張機能の EchoHello メソッドを使用する簡単なテスト アプリケーションを作成します。

    簡単なテスト アプリケーションを作成するには

    1. Visual Studio で、コンソール アプリケーション テンプレートまたは Windows フォーム アプリケーション テンプレートを使用するソリューションを作成します。この手順のステップでは、Windows フォーム アプリケーション テンプレートを使用します。たとえば、アプリケーションに TestHello という名前を付けます。

      注意

      テスト アプリケーション用に独立した Visual Studio ソリューションを作成してください。テスト プロジェクトを HelloService ソリューションに追加すると、テスト アプリケーションを使用して PSI 拡張機能をデバッグできなくなります。

    2. 次の参照を追加します。

      • System.Runtime.Serialization

      • System.ServiceModel

    3. HelloService サービスへの参照を追加します。ソリューション エクスプローラーで、TestHello プロジェクトを右クリックし、[サービス参照の追加] をクリックします。[サービス参照の追加] ダイアログ ボックスで、サービスの URL を入力します。たとえば、「https://localhost/pwa/_vti_bin/psi/HelloService.svc」と入力し、[移動] をクリックします。名前空間名を入力します。たとえば、「SvcHello」と入力し (図 2)、[OK] をクリックします。

      図 2. HelloService サービスへの参照を追加する

      サービス参照の追加

    4. プロジェクトに App.config ファイルを追加します。TestHello プロジェクトを右クリックし、[新しい項目の追加] をクリックします。[新しい項目の追加 – TestHello] ダイアログ ボックスで、[アプリケーション構成ファイル] テンプレートをクリックし、ファイルに App.config という名前を付けて、[追加] をクリックします。

    5. App.config ファイルを開き、内容をすべて削除して、次のコードをファイルに貼り付けます。

      <?xml version="1.0" encoding="utf-8" ?>
      <configuration>
        <system.serviceModel>
          <behaviors>
            <endpointBehaviors>
              <behavior name="basicHttpBehavior">
                <clientCredentials>
                  <windows allowedImpersonationLevel="Impersonation" />
                </clientCredentials>
              </behavior>
            </endpointBehaviors>
          </behaviors>
          <bindings>
            <basicHttpBinding>
              <binding name="basicHttpConf" sendTimeout="01:00:00" maxBufferSize="500000000"
                maxReceivedMessageSize="500000000">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                  maxBytesPerRead="4096" maxNameTableCharCount="500000000" />
                <security mode="TransportCredentialOnly">
                  <transport clientCredentialType="Ntlm" realm="" />
                </security>
              </binding>
              <binding name="BasicHttpBinding_IHello" closeTimeout="00:01:00"
                openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                useDefaultWebProxy="true">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                  maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                <security mode="TransportCredentialOnly">
                  <transport clientCredentialType="Ntlm" proxyCredentialType="None"
                    realm="" />
                  <message clientCredentialType="UserName" algorithmSuite="Default" />
                </security>
              </binding>
            </basicHttpBinding>
          </bindings>
          <client>
            <endpoint address="https://ServerName/ProjectServerName/_vti_bin/PSI/HelloService.svc"
              behaviorConfiguration="basicHttpBehavior" binding="basicHttpBinding"
              bindingConfiguration="basicHttpConf" contract="SvcHello.IHello"
              name="basicHttp_HelloService" />
          </client>
        </system.serviceModel>
      </configuration>
      

      使用中のサーバー名と Project Web App 名に合わせてエンドポイント アドレスのアドレスを変更します。WCF ベースの Project Server アプリケーションの App.config ファイルの詳細については、「[ウォークスルー] WCF を使用して PSI アプリケーションを開発する」を参照してください。

      注意

      endpoint 要素の contract 属性には、ステップ 2.c. で追加したサービス参照の名前空間と、インターフェイスの型名が含まれます。

  3. In ソリューション エクスプローラーで、Form1.cs ファイルを削除します。Program.cs ファイルを開き、内容をすべて削除して、次のコードを貼り付けます。

    using System;
    using System.Windows.Forms;
    
    namespace TestHello
    {
        static class Program
        {
            [STAThread]
            static void Main()
            {
                SvcHello.HelloClient helloClient = null;
                string message = string.Empty;
    
                try
                {
                    helloClient = new SvcHello.HelloClient("basicHttp_HelloService");
    
                    message = helloClient.EchoHello();
                }
                catch (System.ServiceModel.FaultException ex)
                {
                    message =  "System.ServiceModel.FaultException:\n\n";
                    message += ex.Message + "\n\nInnerException:\n";
                    message += ex.InnerException;
                }
                catch (System.ServiceModel.CommunicationException ex)
                {
                    message = "System.ServiceModel.CommunicationException:\n\n";
                    message += "Source: " + ex.Source + "\n\n";
                    message += ex.Message;
                }
                finally
                {
                    // Close the client.
                    if (helloClient != null) helloClient.Close();
                }
                MessageBox.Show(message, "Test HelloService");
            }
        }
    }
    
  4. F5 キーを押して TestHello アプリケーションを実行します。

TestHello アプリケーションは HelloClient オブジェクトの EchoHello メソッドを呼び出し、メッセージ ボックスを表示します (図 3)。

図 3. TestHello アプリケーションで HelloService を使用する

単純なアプリケーションでの PSI 拡張機能の使用

PSI 拡張機能を変更する

HelloService プロジェクトの EchoHello メソッドを変更し、メソッドのシグネチャを変更し、または IHello インターフェイスと Hello クラスに新しいメソッドを追加しても、同じ TestHello アプリケーションをそのまま使用できます。たとえば、手順 4. は、HelloService 拡張機能内で、PSI の Resource サービスのメソッドを呼び出す方法を示しています。

PSI 拡張機能内で PSI のメソッドを呼び出すときは、App.config ファイルを使用する代わりに、PSI サービスの WCF バインドおよびエンドポイントをプログラムで構成する必要があります。ProjectServerServices.dll プロキシ アセンブリを PSI 拡張機能と共にインストールしなくて済むようにするには、Project 2010 SDK にある PSI プロキシ ソース ファイルを追加します。

手順 4. PSI への呼び出しを追加してサービスを変更するには

  1. Visual Studio で、HelloService ソリューションを閉じ、別のディレクトリにソリューションをコピーします。たとえば、HelloService2 というディレクトリを作成し、ソリューションをコピーします。

    HelloService2 ディレクトリ内のファイル名、名前空間、または型名は変更しないでください。手順 4. の例では、IHello インターフェイスは変わっていません。

  2. HelloService2 ディレクトリの HelloService ソリューションを開きます。Microsoft.Office.Project.Server.Library への参照を追加し、Hello.cs ファイルに次の using ステートメントを追加します。

    using System.ServiceModel.Activation;
    using PSLibrary = Microsoft.Office.Project.Server.Library;
    
  3. Project 2010 SDK から Resource サービスの wcf.Resource.cs プロキシ ファイルをソリューションに追加します。プロキシ ファイルの名前空間は SvcResource です。

  4. ResourceClient オブジェクトのクラス変数を追加します。

    private static SvcResource.ResourceClient resourceClient;
    
  5. Helpers 領域内に SetClientEndpoint メソッドを追加します。このメソッドは resourceClient 変数を初期化します。

    /// <summary>
    /// Set the endpoint and initialize the resourceClient variable.
    /// </summary>
    /// <returns>The URL of the custom PSI service.</returns>
    private static string SetClientEndpoint()
    {
        // The maximum size constant must match the MAXSIZE value in the App.config 
        // file of the calling application.
        const int MAXSIZE = 500000000;
        const string PSI_SHARED = "_vti_bin/PSI/";
        const string ROUTER_SERVICE = "_vti_bin/PSI/ProjectServer.svc";
    
        Uri serviceUri = GetServiceUri();
    
        string serviceUrl = serviceUri.ToString();
    
        int indexOfPsi = serviceUrl.IndexOf(PSI_SHARED);
        string pwaUrl = serviceUrl.Remove(indexOfPsi);
        string routerService = pwaUrl + ROUTER_SERVICE;
    
        BasicHttpBinding binding = null;
    
        if (serviceUri.Scheme.Equals(Uri.UriSchemeHttps))
        {
            // Create binding for HTTPS.
            binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
        }
        else
        {
            // Create binding for HTTP.
            binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);
        }
    
        binding.Name = "basicHttpConf";
        binding.AllowCookies = true;
        binding.MessageEncoding = WSMessageEncoding.Text;
    
        binding.OpenTimeout = TimeSpan.FromHours(1);
        binding.ReceiveTimeout = TimeSpan.FromHours(1);
        binding.SendTimeout = TimeSpan.FromHours(1);
    
        // If the TransferMode is buffered, the MaxBufferSize and 
        // MaxReceived MessageSize must be the same value.
        binding.TransferMode = TransferMode.Buffered;
        binding.MaxBufferSize = MAXSIZE;
        binding.MaxReceivedMessageSize = MAXSIZE;
        binding.ReaderQuotas.MaxArrayLength = MAXSIZE;
        binding.ReaderQuotas.MaxNameTableCharCount = MAXSIZE;
    
        binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
        binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.Ntlm;
        binding.Security.Transport.Realm = "";
    
        // The endpoint address is the ProjectServer.svc router for all public PSI calls.
        EndpointAddress address = new EndpointAddress(routerService);
    
        resourceClient = new SvcResource.ResourceClient(binding, address);
        resourceClient.ChannelFactory.Credentials.Windows.AllowedImpersonationLevel
            = TokenImpersonationLevel.Impersonation;
        resourceClient.ChannelFactory.Credentials.Windows.AllowNtlm = true;
    
        return serviceUrl;
    }
    

    HelloService 拡張機能では、serviceUrl の値は、たとえば https://localhost/pwa/_vti_bin/PSI/HelloService.svc になります。変更した PSI 拡張機能では Resource サービスを使用するので、エンドポイントを ProjectServer.svc のアドレスに設定する必要があります。これが PSI への呼び出しのルーターとして機能します。routerService の値は https://localhost/pwa/_vti_bin/PSI/ProjectServer.svc になります。

    WCF ベースの Project Server アプリケーションをプログラムで構成する方法の詳細については、「[ウォークスルー] WCF を使用して PSI アプリケーションを開発する」を参照してください。

  6. EchoHello メソッドを次のように変更します。

    public string EchoHello()
    {
        // Initialize the resourceClient variable.
        // The serviceUrl variable is used only for information in this example.
        string serviceUrl = SetClientEndpoint();
    
        Guid userUid = resourceClient.GetCurrentUserUid();
        SvcResource.ResourceDataSet dsResource = resourceClient.ReadResource(userUid);
    
        string userName = dsResource.Resources[0].RES_NAME;
        string userEmail = dsResource.Resources[0].WRES_EMAIL;
    
        string message = "Hello from the WCF service:\n" + serviceUrl;
        message += "\n\nThe following user called the service:\n";
        message += "\tName: " + userName + "\n\tEmail: " + userEmail;
    
        return message;
    }
    

    サンプル コードでは、Resource サービスの 2 つのメソッドを呼び出しています。ReadResource メソッドを使用するにはリソースの GUID が必要なので、GetCurrentUserUid で GUID を取得しています。サンプル コードでは、ResourceDataSet の Resources テーブルから現在のユーザーのリソース名と電子メールのプロパティのみを取得しています。

  7. HelloService2 ディレクトリにある変更した HelloService ソリューションをコンパイルします。

変更したサービスを展開およびテストする

アセンブリ名、名前空間名、およびインターフェイス名は変更されていないので、同じ TestHello アプリケーションを使用して、変更した HelloService 拡張機能をテストすることができます。展開で必要なのは、変更した HelloServer.dll を GAC にインストールし、iisreset を実行することだけです。

手順 5. 変更したサービスを展開およびテストするには

  1. [Visual Studio コマンド プロンプト] を開き、HelloService2\bin\debug ディレクトリに移動して、次のコマンドを実行します。

    gacutil /if HelloService.dll
    iisreset
    
  2. Internet Explorer でサービスの表示を更新します。PSI 拡張機能のアドレスは、手順 3. のときと同じ https://localhost/pwa/_vti_bin/psi/helloservice.svc です。Internet Explorer には、図 1 と同じタブが表示されます。

  3. Visual Studio で、TestHello ソリューションを開きます。名前空間名、インターフェイス名、および EchoHello メソッド シグネチャは変更されていないので、TestHello アプリケーションや構成ファイルを変更する必要はありません。

    重要

    IHello インターフェイスおよび Hello クラスで EchoHello メソッド シグネチャを変更した場合、またはメソッドを追加した場合は、サービス参照を更新する必要があります。ソリューション エクスプローラーで、[サービスの参照] フォルダーの SvcHello を右クリックし、[サービス参照の更新] をクリックします。

  4. F5 キーを押して TestHello アプリケーションを実行します。

TestHello アプリケーションは、HelloClient オブジェクトの変更された EchoHello メソッドを呼び出し、Resource サービスからのデータを含むメッセージ ボックスを表示します (図 4)。

図 4. TestHello アプリケーションで、変更された HelloService を使用する

変更された HelloService 拡張機能の使用

PSI 拡張機能をデバッグする

PSI 拡張機能を Visual Studio でデバッグするには、w3wp.exe というインターネット インフォメーション サービス (IIS) ワーカー プロセスに拡張機能プロジェクトをアタッチする必要があります。アタッチは、サービスを再コンパイルし、展開し、Internet Explorer でテストした後で行う必要があります。プロジェクトを適切な w3wp プロセスにアタッチすると、プロセスが Visual Studio で実行され、ブレークポイントがアクティブになります。手順 6. に、適切な w3wp プロセスを見つける方法を示します。

手順 6. 変更した HelloService サービスをデバッグするには

  1. HelloService プロジェクトで何か変更を加えた場合は、プロジェクトを再コンパイルします。

  2. 手順 5. のステップ 1. とステップ 2. に従って、サービスを展開します。Internet Explorer の表示を更新して、HelloService がアクティブかどうかを確認し、サービスが使用する w3wp プロセスをリセットします。

  3. Hello.cs ファイルにブレークポイントを設定します。たとえば、32 行目 (string userName = dsResource.Resources[0].RES_NAME;) にブレークポイントを設定します。

  4. Visual Studio で、[デバッグ] メニューの [プロセスにアタッチ] をクリックします。[プロセスにアタッチ] ダイアログ ボックスで、[すべてのユーザーからのプロセスを表示する] チェック ボックスおよび [すべてのセッションのプロセスを表示する] チェック ボックスをオンにします (図 5)。

    図 5. デバッグ用に w3wp プロセスにアタッチする

    デバッグのために w3wp プロセスに接続

  5. w3wp プロセスを選択し、[適用] をクリックします。w3wp プロセスが複数ある場合は、次のいずれかの方法を使用して、適切なプロセスを見つけます。

    • すべての w3wp プロセスにアタッチします。

    • 1 つのプロセスを選択し、[適用] をクリックします。それが適切なプロセスでない場合は、ブレークポイントが無効なアイコンとして表示され、ブレークポイントをヒットできないことを示すヒントが表示されます (図 6)。デバッグを停止し (Shift + F5 キーを押す)、別の w3wp プロセスにアタッチします。

      図 6. 正しくない w3wp プロセスにアタッチするとブレークポイントが無効になる

      誤った処理によりブレークポイントが無効になる

    • 前の方法がどれもうまくいかない場合は、HelloService 拡張機能を再コンパイルして再展開し、iisreset を実行して、Internet Explorer で HelloService の表示を更新します。ブレークポイント アイコンが赤色のままになるまで、前の方法を繰り返し試します。

  6. Visual Studio の別のインスタンスで、TestHello ソリューションを開き、デバッグを開始します (F5 キーを押します)。

HelloService を実行している Visual Studio のインスタンスが適切な w3wp プロセスにアタッチされていると、TestHello インスタンスからのデバッグは、HelloService インスタンスの赤色のブレークポイントで停止します。

Project Server 拡張機能の推奨ガイドライン

Project Server 2010 の PSI 拡張機能を開発する場合の推奨ガイドラインを次に示します。

  • PSI 拡張機能を使用して、Project Server データベース オブジェクト (テーブル、ビュー、ストアド プロシージャなど) を直接変更しないでください。

  • Project Server データの読み取りと操作には、拡張機能内の組み込みの PSI メソッドを使用します。

  • RDB から Project Server データを読み取ることも、RDB で追加の目的のためにテーブルとビューを作成することもできます。

  • PSI 拡張機能にセキュリティを組み込みます。アクセスする権限のないユーザーにデータを返さないようにします。

  • PSI メソッドは、多くの状況で実行時例外をスローすることがあります。サービスが理にかなった応答メッセージをクライアント アプリケーションに返すように、すべてのコードを try/catch ブロックで保護してください。

関連項目

タスク

[ウォークスルー] WCF を使用して PSI アプリケーションを開発する

その他のリソース

PSI 拡張機能の開発

[ウォークスルー] PSI 拡張機能を作成する

AspNetCompatibilityRequirementsMode Enumeration

ブログ記事: How to Make PSI Extensions in Project Server 2010—Part I (英語)

ブログ記事: How to Make PSI Extensions in Project Server 2010—Part II (英語)