PerformancePoint Services の表形式データ ソースのエディターを作成する
最終更新日: 2011年8月30日
適用対象: SharePoint Server 2010
Microsoft SharePoint Server 2010 の PerformancePoint Services では、カスタム エディターによってユーザーはカスタム オブジェクトのプロパティを設定できます。カスタム エディターは、編集コントロールを提供し、リポジトリのカスタム オブジェクトを取得および更新します。エディター機能の詳細については、「カスタム PerformancePoint Services オブジェクトのエディター」を参照してください。
適用先: PerformancePoint Services for SharePoint Server (Enterprise バージョン)
このトピックの手順とコード例は、「カスタム オブジェクト サンプル」の SampleDataSourceEditor クラスに基づいています。エディターはシン Web アプリケーションです。ユーザーは、これを使用して、データ ソースの名前と説明の変更、株式シンボルの入力、プロキシ サーバー アドレスとキャッシュ ファイルの場所の指定ができます。クラスの完全なコードは、このトピックの「使用例」セクションに掲載されています。
注意
サンプル エディターをテンプレートとして使用することをお勧めします。サンプルは、PerformancePoint Services API でオブジェクトを呼び出す方法、(オブジェクトの作成、更新などの) リポジトリ操作のためにヘルパー オブジェクトによる呼び出しを単純化する方法、PerformancePoint Services 開発のためのベスト プラクティスを示します。
データ ソース エディターを作成するには、以下の 2 つの基本手順を実行します。
エディター クラスを作成して設定する
機能を定義して編集する
カスタム エディターを作成するには、エディター クラスの作成から始めます。
エディター クラスを作成して設定するには
PerformancePoint Services をインストールするか、拡張機能が使用する (手順 3. で示した) DLL をコンピューターにコピーします。詳細については、「開発シナリオで使用される PerformancePoint Services DLL」を参照してください。
Visual Studio で、C# クラス ライブラリを作成します。拡張機能のためのクラス ライブラリを既に作成している場合、新しい C# クラスを追加します。
プロジェクトに、アセンブリ参照として以下の DLL を追加します。
Microsoft.PerformancePoint.Scorecards.Client.dll
Microsoft.SharePoint.dll (ヘルパー クラスが使用)
サンプル エディターには、System.Core.dll、System.Web.dll、System.Web.Services.dll、および System.Xml.Linq.dll へのアセンブリ参照も含まれます。拡張機能の機能によっては、その他のプロジェクト参照が必要になることがあります。
サンプルから以下のクラスをプロジェクトに追加します。エディターは、これらのヘルパー クラスを使用して、PerformancePoint Services リポジトリとキャッシュ ファイルを操作します。
ExtensionRepositoryHelper.cs
DataSourceRepositoryHelper.cs
SampleDSCacheHandler.cs
エディター クラスで、Microsoft.PerformancePoint.Scorecards 名前空間の using ディレクティブを追加します。拡張機能の機能によっては、その他の using ディレクティブが必要になることがあります。
エディターの実装をサポートする基底クラスから継承します。サンプルのデータ ソース エディターは Web アプリケーションなので、Page クラスから継承します。他の実装では、UserControl、WebPart クラスなどの基底クラスから派生できます。
エディター クラスを作成して設定した後で、エディターの機能を定義する必要があります。
編集機能を定義するには
ユーザーが表示または変更できるプロパティを表示するコントロールの変数を宣言します。サンプルのデータ ソース エディターでは、最初にユーザー インターフェイス コンポーネント (ASPX ページ) で定義されている Web サーバー コントロールの変数を宣言します。サンプル エディターでは、ユーザーが変更を送信できるボタン コントロールも定義します。次に、エディターで CreateChildControls() メソッドを呼び出して、これらのコントロールをページで使用できるようにします。
注意
エディターは、ユーザー インターフェイスとは別のプログラミング ロジックを定義します。エディターのユーザー インターフェイス コンポーネントを作成するための説明は、この文書の範囲外となります。
クエリ文字列からパラメーターを取得し、それらを以下のコード例で示すローカル変数のための値として設定します。
// The URL of the site collection that contains the PerformancePoint Services repository. string server = Request.QueryString[ClickOnceLaunchKeys.SiteCollectionUrl]; // The location of the data source in the repository. string itemLocation = Request.QueryString[ClickOnceLaunchKeys.ItemLocation]; // The operation to perform: OpenItem or CreateItem. string action = Request.QueryString[ClickOnceLaunchKeys.LaunchOperation];
クエリ文字列パラメーターの詳細については、「カスタム PerformancePoint Services オブジェクトのエディター」を参照してください。
以下のコード例で示すように、リポジトリに呼び出しをするための DataSourceRepositoryHelper オブジェクトを取得します。
DataSourceRepositoryHelper = new DataSourceRepositoryHelper();
以下のコード例のように、クエリ文字列パラメーターに基づいてデータ ソースの場所を設定します。
RepositoryLocation repositoryDataSourceLocation = RepositoryLocation.CreateFromUriString(itemLocation);
以下のコード例のように、クエリ文字列から実行する操作 (OpenItem または CreateItem) を取得し、カスタム データ ソースを取得または作成します。
if (ClickOnceLaunchValues.OpenItem.Equals(action, StringComparison.OrdinalIgnoreCase)) { // Use the repository-helper object to retrieve the data source. datasource = dataSourceRepositoryHelper.Get(repositoryDataSourceLocation); if (datasource == null) { displayError("Could not retrieve the data source for editing."); return; } } else { displayError("Invalid Action."); return; }
カスタム データ ソースを取得するには、DataSourceRepositoryHelper.Get メソッドを使用します。
カスタム データ ソースを作成するには、DataSource() コンストラクターを使用し、データ ソースの Name および SubTypeId プロパティを定義します。SubTypeId は、データ ソースの一意の識別子です。これは、PerformancePoint Services web.config ファイルに指定するカスタム データ ソースの subType 属性と一致する必要があります。
注意
サンプルのデータ ソース エディターに、データ ソース オブジェクトを作成するためのロジックは含まれていません。カスタム オブジェクトの作成例については、「[方法] PerformancePoint Services レポートのエディターを作成する」または「[方法] PerformancePoint Services フィルターのエディターを作成する」を参照してください。
注意
既定では、ユーザーは PerformancePoint ダッシュボード デザイナーからのみカスタム オブジェクトを作成できます。ユーザーにダッシュボード デザイナーの外でカスタム オブジェクトを作成できるようにするには、リポジトリのコンテンツ タイプから CreateItem 要求をエディターに送るメニュー項目を追加する必要があります。詳細については、「カスタム PerformancePoint Services オブジェクトのエディター」を参照してください。
サンプルのデータ ソース エディターでは、手順 2. ~ 5. が Page_Load メソッドで実行されます。変数とコントロールの初期化と検証、コントロールへのデータの挿入、カスタム データ ソースとヘルパー オブジェクトの状態情報の保存にも、Page_Load が使用されます。
ユーザー定義の変更でデータ ソースを更新します。サンプルのデータ ソース エディターは、DataSourceRepositoryHelper.Update メソッドを呼び出して、リポジトリ内のデータ ソース オブジェクトの Name、Description、および CustomData プロパティを更新します。CustomData を使用して、シリアル化されたオブジェクトまたは文字列を格納できます。サンプル エディターは、これを使用して、ユーザー定義の株式シンボル、株の時価を格納するキャッシュ ファイルの場所、プロキシ サーバーの場所を格納します。
注意
ユーザーは、カスタム オブジェクトの Name、Description、および Owner ([責任者]) プロパティを編集して、ダッシュボード デザイナーおよび PerformancePoint Services リポジトリからカスタム オブジェクトを直接削除することができます。
列のマッピングが定義されていない場合、データ ソース プロバイダーを呼び出して、列のマッピングを定義します。
サンプルのデータ ソース エディターでは、手順 6. ~ 7. が buttonOK_Click および CreateCacheFile メソッドで実行されます。また、buttonOK_Click を使用すると、AreAllInputsValid メソッドを呼び出し、コントロールのコンテンツの検証、およびカスタム データ ソースとヘルパー オブジェクトの状態情報の取得も行われます。
次の手順: データ ソース エディター (必要な場合は、そのユーザー インターフェイスも含む) とデータ ソース プロバイダーを作成した後、「[方法] PerformancePoint Services の拡張機能を手動で登録する」に説明されているとおりに拡張機能を展開します。データ ソースの拡張機能のサンプルをインストールする方法については、「コード サンプル: カスタム レポート、フィルター、および表形式データ ソース オブジェクト」の「サンプルのレポート、フィルター、およびデータ ソース オブジェクトのインストール」セクションを参照してください。
例
以下のコード例は、リポジトリ内のカスタムの表形式データ ソースの取得と更新を行い、ASPX ページに定義されたコントロールのプログラミング ロジックを提供します。
注意
このコード例をコンパイルする前に、「エディター クラスを作成して設定するには」で説明している開発環境を設定する必要があります。
using System;
using System.IO;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.PerformancePoint.Scorecards;
using System.Xml.Linq;
namespace Microsoft.PerformancePoint.SDK.Samples.SampleDataSource
{
// Represents the class that defines the sample data source editor.
public class SampleDataSourceEditor : Page
{
#region Members
// Declare private variables for the ASP.NET controls defined in the user interface.
// The user interface is an ASPX page that defines the controls in HTML.
private TextBox textboxName;
private TextBox textboxDescription;
private TextBox textboxStockSymbols;
private TextBox textboxXMLLocation;
private TextBox textboxProxy;
private Label labelErrorMessage;
private Button buttonOK;
#endregion
#region Page methods and events
// Make the controls available to this class.
protected override void CreateChildControls()
{
base.CreateChildControls();
if (null == textboxProxy)
textboxProxy = FindControl("textboxProxy") as TextBox;
if (null == textboxName)
textboxName = FindControl("textboxName") as TextBox;
if (null == textboxDescription)
textboxDescription = FindControl("textboxDescription") as TextBox;
if (null == textboxStockSymbols)
textboxStockSymbols = FindControl("textboxStockSymbols") as TextBox;
if (null == textboxXMLLocation)
textboxXMLLocation = FindControl("textboxXMLLocation") as TextBox;
if (null == labelErrorMessage)
labelErrorMessage = FindControl("labelErrorMessage") as Label;
if (null == buttonOK)
buttonOK = FindControl("buttonOK") as Button;
}
// Handles the Load event of the Page control.
// Methods that use a control variable should call the Control.EnsureChildControls
// method before accessing the variable for the first time.
protected void Page_Load(object sender, EventArgs e)
{
// Initialize controls the first time the page loads only.
if (!IsPostBack)
{
EnsureChildControls();
DataSourceRepositoryHelper dataSourceRepositoryHelper = null;
try
{
// Get information from the query string parameters.
string server = Request.QueryString[ClickOnceLaunchKeys.SiteCollectionUrl];
string itemLocation = Request.QueryString[ClickOnceLaunchKeys.ItemLocation];
string action = Request.QueryString[ClickOnceLaunchKeys.LaunchOperation];
// Validate the query string parameters.
if (string.IsNullOrEmpty(server) ||
string.IsNullOrEmpty(itemLocation) ||
string.IsNullOrEmpty(action))
{
displayError("Invalid URL.");
return;
}
// Retrieve the repository-helper object.
dataSourceRepositoryHelper =
new DataSourceRepositoryHelper();
// Set the data source location.
RepositoryLocation repositoryDataSourceLocation = RepositoryLocation.CreateFromUriString(itemLocation);
DataSource datasource;
// Retrieve the data source object by
// using the repository-helper object.
if (ClickOnceLaunchValues.OpenItem.Equals(action, StringComparison.OrdinalIgnoreCase))
{
datasource = dataSourceRepositoryHelper.Get(repositoryDataSourceLocation);
if (datasource == null)
{
displayError("Could not retrieve the data source for editing.");
return;
}
}
else
{
displayError("Invalid Action.");
return;
}
// Save the original data source and helper objects across page postbacks.
ViewState["action"] = action;
ViewState["datasource"] = datasource;
ViewState["datasourcerepositoryhelper"] = dataSourceRepositoryHelper;
// Populate the child controls.
if (null != datasource.Name)
textboxName.Text = datasource.Name.ToString();
if (null != datasource.Description)
textboxDescription.Text = datasource.Description.ToString();
if (null != datasource.CustomData)
{
string[] splitCustomData = datasource.CustomData.Split('&');
if (splitCustomData.Length > 2)
{
textboxStockSymbols.Text = splitCustomData[0];
textboxXMLLocation.Text = splitCustomData[1].Replace(@"\SampleStockQuotes.xml", string.Empty);
textboxProxy.Text = splitCustomData[2];
}
}
}
catch (Exception ex)
{
displayError("An error has occurred. Please contact your administrator for more information.");
if (dataSourceRepositoryHelper != null)
{
// Add the exception detail to the server
// event log.
dataSourceRepositoryHelper.HandleException(ex);
}
}
}
}
// Handles the Click event of the buttonOK control.
protected void buttonOK_Click(object sender, EventArgs e)
{
EnsureChildControls();
// Verify that the required fields contain values.
if (!AreAllInputsValid())
return;
// Clear any pre-existing error message.
labelErrorMessage.Text = string.Empty;
// Retrieve the data source and helper objects from view state.
string action = (string)ViewState["action"];
DataSource datasource = (DataSource)ViewState["datasource"];
DataSourceRepositoryHelper datasourcerepositoryhelper = (DataSourceRepositoryHelper)ViewState["datasourcerepositoryhelper"];
// Update the data source object with form changes.
datasource.Name.Text = textboxName.Text;
datasource.Description.Text = textboxDescription.Text;
// Define column mappings if they aren't already defined.
if (datasource.DataTableMapping.ColumnMappings.Count <= 0)
{
datasource.DataTableMapping = WSTabularDataSourceProvider.CreateDataColumnMappings();
}
// Save the data source to the repository
// by using the repository-helper object.
try
{
CreateCacheFile(datasource);
datasource.Validate();
if (ClickOnceLaunchValues.OpenItem.Equals(action, StringComparison.OrdinalIgnoreCase))
{
datasourcerepositoryhelper.Update(datasource);
}
else
{
displayError("Invalid Action.");
}
}
catch (Exception ex)
{
displayError("An error has occurred. Please contact your administrator for more information.");
if (datasourcerepositoryhelper != null)
{
// Add the exception detail to the server event log.
datasourcerepositoryhelper.HandleException(ex);
}
}
}
#endregion
#region Helper methods
// Display the error string in the labelErrorMessage label.
void displayError(string msg)
{
EnsureChildControls();
labelErrorMessage.Text = msg;
// Disable the OK button because the page is in an error state.
buttonOK.Enabled = false;
return;
}
// Validate the text box inputs.
bool AreAllInputsValid()
{
if (string.IsNullOrEmpty(textboxProxy.Text))
{
labelErrorMessage.Text = "The proxy server address is required.";
return false;
}
if (string.IsNullOrEmpty(textboxXMLLocation.Text))
{
labelErrorMessage.Text = "The location to save the cache file to is required.";
return false;
}
if (string.IsNullOrEmpty(textboxName.Text))
{
labelErrorMessage.Text = "A data source name is required.";
return false;
}
if (string.IsNullOrEmpty(textboxStockSymbols.Text))
{
labelErrorMessage.Text = "A stock symbol is required.";
return false;
}
return true;
}
// Create the XML cache file at the specified location and
// store it and the stock symbols in the CustomData
// property of the data source.
void CreateCacheFile(DataSource datasource)
{
string cacheFileLocation = string.Format("{0}\\{1}", textboxXMLLocation.Text.TrimEnd('\\'),
"SampleStockQuotes.xml");
datasource.CustomData = string.Format("{0}&{1}&{2}", textboxStockSymbols.Text, cacheFileLocation, textboxProxy.Text);
// Check if the cache file already exists.
if (!File.Exists(cacheFileLocation))
{
// Create the cache file if it does not exist.
XDocument doc = SampleDSCacheHandler.DefaultCacheFileContent;
doc.Save(cacheFileLocation);
}
}
#endregion
}
}
コードのコンパイル
このコード例をコンパイルする前に、「エディター クラスを作成して設定するには」で説明している開発環境を設定する必要があります。
セキュリティ
DLL には厳密な名前で署名する必要があります。さらに、DLL によって参照されたすべてのアセンブリが厳密な名前を持つことを確認してください。厳密な名前を使用してアセンブリに署名する方法の詳細、および公開/秘密キーのペアを作成する方法の詳細については、「How to: Create a Public/Private Key Pair」を参照してください。
関連項目
タスク
[方法] PerformancePoint Services の表形式データ ソースのプロバイダーを作成する
概念
カスタム PerformancePoint Services オブジェクトのエディター