Erstellen von tabellarischen Datenquellen-Editoren für PerformancePoint-Dienste in SharePoint
In diesem Artikel erfahren Sie, wie die Editor-Komponente einer benutzerdefinierten Datenquellenerweiterung in Tabellenform für PerformancePoint-Dienste erstellt wird.
Was sind benutzerdefinierte Daten Editoren für PerformancePoint-Dienste ?
Editoren für benutzerdefinierte Daten aktivieren PerformancePoint-Dienste Benutzer auf benutzerdefinierten tabellarischen Datenquellen Eigenschaften festlegen. Weitere Informationen zu Editor Anforderungen und Funktionen finden Sie unter Editoren für benutzerdefinierte PerformancePoint Services-Objekte.
Die folgenden Verfahren und Codebeispiele basieren auf der SampleDataSourceEditor -Klasse aus der benutzerdefinierten Objekte (Beispiel). Der Editor ist eine dünne Anwendung, die ermöglicht Benutzern den Namen und eine Beschreibung der Datenquelle ändern, geben Aktiensymbole, und einen Proxy-Server-Adresse und der Cache die Dateispeicherort angeben. Den vollständigen Code für die -Klasse finden Sie unter Codebeispiel: Abrufen und Aktualisieren benutzerdefinierter tabellarischer Datenquellen.
Es wird empfohlen, dass Sie den Beispiel-Editor als Vorlage verwenden. Das Beispiel zeigt wie Objekte aufrufen PerformancePoint-Dienste-API bietet Hilfsobjekte, die vereinfachen von Anrufen für Repository-Vorgänge (wie erstellen und Aktualisieren der Objekte), und bewährte Methoden für die Entwicklung von PerformancePoint-Dienste veranschaulicht.
Erstellen von Editoren für benutzerdefinierte PerformancePoint-Dienste tabellarische Datenquellen
Installieren Sie PerformancePoint-Dienste, oder kopieren Sie die DLLs, die die Erweiterung verwendet (siehe Schritt 3) auf Ihrem Computer. Weitere Informationen finden Sie unter DLLs mit Klassenbibliotheken.
Erstellen Sie in Visual Studio eine C#-Klassenbibliothek. Sollten Sie bereits eine Klassenbibliothek für die Erweiterung erstellt haben, fügen Sie eine neue C#-Klasse hinzu.
Sie müssen die DLL mit einem starken Namen signieren. Stellen Sie außerdem sicher, dass alle Assemblys, auf die von der DLL verwiesen wird, ebenfalls starke Namen haben. Informationen zum Signieren einer Assembly mit einem starken Namen und zum Erstellen eines öffentlichen/privaten Schlüsselpaars finden Sie unter Vorgehensweise: Erstellen eines öffentlichen/privaten Schlüsselpaars.
Fügen Sie dem Projekt die folgenden DLLs als Assemblyverweise hinzu:
- Microsoft.PerformancePoint.Scorecards.Client.dll
- Microsoft.SharePoint.dll (used by helper classes)
The sample editor also contains assembly references to System.Core.dll, System.Web.dll, System.Web.Services.dll, and System.Xml.Linq.dll. Depending on your extension's functionality, other project references may be required.
Fügen Sie dem Projekt die folgenden Klassen aus dem Beispiel. Editor wird zur Interaktion mit dem Repository PerformancePoint-Dienste und die Cachedatei Hilfsklassen verwendet:
- ExtensionRepositoryHelper.cs
- DataSourceRepositoryHelper.cs
- SampleDSCacheHandler.cs
Fügen Sie in Ihrer Editorklasse eine using-Direktive für den Microsoft.PerformancePoint.Scorecards-Namespace hinzu. Je nach Funktionalität der Erweiterung sind u. U. andere using-Direktiven erforderlich.
Übernehmen Sie von der Basisklasse, die die Implementierung Ihres Editors unterstützt. Da der Beispieldatenquellen-Editor eine Webanwendung ist, erbt er von der Page-Klasse . Andere Implementierungen können von Basisklassen wie der UserControl -Klasse oder der WebPart -Klasse erben.
Deklarieren Sie Variablen für die Steuerelemente, mit denen die Eigenschaften verfügbar gemacht werden, die die Benutzer anzeigen oder ändern sollen. Mit dem Beispiel-Datenquellen-Editor werden zunächst Variablen für die Webserversteuerelemente deklariert, die in der Benutzeroberflächenkomponente definiert sind, wobei es sich um eine ASPX-Seite handelt. Außerdem wird mit dem Beispieleditor ein Schaltflächensteuerelement definiert, mit dem Benutzer Änderungen senden können. Anschließend ruft der Editor die CreateChildControls() -Methode auf, um die Steuerelemente auf der Seite verfügbar zu machen.
Hinweis
Im Editor wird die Programmierlogik separat von der Benutzeroberfläche definiert. Anweisungen zum Erstellen der Benutzeroberflächenkomponenten würden den Rahmen dieser Dokumentation sprengen.
Das Beispiel Datenquellen-Editors führt die Schritte 8 bis 11 in der Page_Load -Methode. Page_Load wird auch initialisieren und Variablen und Steuerelemente zu überprüfen, füllen Sie Steuerelemente und Statusinformationen für die benutzerdefinierte Daten Quell- und Helper-Objekte zu speichern.
Rufen Sie die Parameter aus der Abfragezeichenfolge ab, und legen Sie sie als Werte für lokale Variablen fest, wie im folgenden Codebeispiel dargestellt.
// 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];
Hinweis
Informationen zu den Abfragezeichenfolgenparametern finden Sie unter Editoren für benutzerdefinierte PerformancePoint-Dienste Objects.
Rufen Sie das DataSourceRepositoryHelper -Objekt, das Tätigen von Anrufen an das Repository verwendet wird, wie im folgenden Codebeispiel gezeigt.
DataSourceRepositoryHelper = new DataSourceRepositoryHelper();
Legen Sie wie im folgenden Codebeispiel dargestellt den Speicherort für die Datenquelle basierend auf dem Abfragezeichenfolgen-Parameter fest.
RepositoryLocation repositoryDataSourceLocation = RepositoryLocation.CreateFromUriString(itemLocation);
Abzurufen Sie Vorgang ( OpenItem oder CreateItem) aus der Abfragezeichenfolge und rufen Sie ab, oder erstellen Sie die benutzerdefinierte Datenquelle.
- Verwenden Sie die DataSourceRepositoryHelper.Get-Methode zum Abrufen der benutzerdefinierten Datenquelle.
- Um die benutzerdefinierte Datenquelle zu erstellen, verwenden Sie den Konstruktor DataSource() und definieren Sie dann die Eigenschaften für die Datenquelle Name und SubTypeId . SubTypeId ist der eindeutige Bezeichner für die Datenquelle, und es muss übereinstimmen, das subType -Attribut, das Sie für die benutzerdefinierte Datenquelle in der PerformancePoint-Dienste web.config-Datei angeben.
Hinweis
Der Beispiel-Datenquellen-Editor enthält keine Logik zum Erstellen eines Datenquellenobjekts. Beispiele zum Erstellen eines benutzerdefinierten Objekts finden Sie unter Vorgehensweise: Erstellen von Berichts-Editoren für PerformancePoint-Dienste in SharePoint oder Vorgehensweise: Erstellen von Filter-Editoren für PerformancePoint-Dienste in SharePoint.
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; }
Hinweis
Standardmäßig können Benutzer benutzerdefinierte Objekte nur über PerformancePoint Dashboard Designer erstellen. Damit Benutzer ein benutzerdefiniertes Objekt außerhalb des Dashboard-Designers erstellen können, müssen Sie ein Menüelement hinzufügen, das eine CreateItem-Anforderung aus dem Inhaltstyp im Repository an Ihren Editor sendet. Weitere Informationen finden Sie unter Editoren für benutzerdefinierte PerformancePoint Services-Objekte.
Der Beispieldatenquellen-Editor führt die Schritte 12 und 13 in den Methoden buttonOK_Click und CreateCacheFile aus. buttonOK_Click wird auch zum Aufrufen der AreAllInputsValid-Methode verwendet, um die Inhalte der Steuerelemente zu überprüfen und Statusinformationen für die benutzerdefinierte Datenquelle und das Hilfsobjekt abzurufen.
Aktualisieren Sie die Datenquelle mit benutzerdefinierten Änderungen. Der Beispiel-Datenquellen-Editor ruft die DataSourceRepositoryHelper.Update-Methode auf, um die Eigenschaften Name , Description und CustomData des Datenquellenobjekts im Repository zu aktualisieren. Mit CustomData können Sie ein serialisiertes Objekt oder eine serialisierte Zeichenfolge speichern. Der Beispiel-Editor speichert damit benutzerdefinierte Aktiensymbole, den Speicherort der Cachedatei, in der Aktienkurswerte gespeichert werden, sowie die Adresse des Proxyservers.
Hinweis
Benutzer können die Eigenschaften Name, Beschreibung und Besitzer (Verantwortliche Person) eines benutzerdefinierten Objekts bearbeiten und benutzerdefinierte Objekte direkt im Dashboard-Designer und im PerformancePoint-Dienste-Repository löschen.
Rufen Sie den Datenquellenanbieter auf, um Spaltenzuordnungen zu definieren, falls noch nicht geschehen.
Codebeispiel: Abrufen und Aktualisieren von benutzerdefinierten PerformancePoint-Dienstdatenquellen in Tabellenform in SharePoint
Im folgenden Codebeispiel wird abgerufen und benutzerdefinierten tabellarischen Datenquellen aktualisiert. Dieser Code hat ihren Ursprung im Editor CodeBehind-Klasse, die die Programmierlogik für Steuerelemente bereitstellt, die in einer ASPX-Seite definiert sind.
Bevor Sie dieses Codebeispiel kompilieren können, müssen Sie Ihre Entwicklungsumgebung wie unter Erstellen und Konfigurieren der Editorklasse für einen Tabellendatenquellen-Editor in PerformancePoint-Dienste beschrieben konfigurieren.
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
}
}
Nächste Schritte
Nachdem Sie einen Datenquellen-Editor (einschließlich seiner Benutzeroberfläche, falls erforderlich) und einen Datenquellenanbieter erstellt haben, stellen Sie die Erweiterung wie unter How to: Manually Register PerformancePoint-Dienste Extensions beschrieben bereit.