Gewusst wie: Erstellen von Editoren für tabularische Datenquellen von PerformancePoint Services
Letzte Änderung: Dienstag, 30. August 2011
In PerformancePoint Services in Microsoft SharePoint Server 2010 können Benutzer mithilfe von benutzerdefinierten Editoren Eigenschaften für benutzerdefinierte Objekte festlegen. Diese Editoren enthalten Bearbeitungssteuerelemente, und mit ihnen können benutzerdefinierte Objekte im Repository abgerufen und aktualisiert werden. Weitere Informationen zur Editorfunktionalität finden Sie unter Editoren für benutzerdefinierte PerformancePoint Services-Objekte.
Gilt für: SharePoint Server 2010
Die Prozeduren und Codebeispiele in diesem Thema basieren auf der SampleDataSourceEditor-Klasse im Beispiel für benutzerdefinierte Objekte. Der Editor ist eine schlanke Webanwendung, mit der Benutzer den Namen und die Beschreibung der Datenquelle ändern, Aktiensymbole eingeben sowie eine Proxyserveradresse und einen Speicherort für die Cachedatei angeben können. Der vollständige Code für die Klasse befindet sich in diesem Thema im Abschnitt "Beispiel".
Hinweis |
---|
Es wird empfohlen, den Beispieleditor als Vorlage zu verwenden. Im Beispiel sehen Sie, wie Sie Objekte in der PerformancePoint Services-API aufrufen, welche Hilfsobjekte Sie zur Vereinfachung von Aufrufen für Repositoryvorgänge (z. B. zum Erstellen und Aktualisieren von Objekten) verwenden können und welche Best Practices bei der PerformancePoint Services-Entwicklung zu beachten sind. |
Zum Erstellen eines Datenquellen-Editors führen Sie die folgenden beiden grundlegenden Verfahren aus:
Erstellen und Konfigurieren der Editorklasse
Definieren der Bearbeitungsfunktionalität
Zum Erzeugen eines benutzerdefinierten Editors erstellen Sie zunächst die Editorklasse.
So erstellen und konfigurieren Sie die Editorklasse
Installieren Sie PerformancePoint Services, oder kopieren Sie die von der Erweiterung verwendeten DLLs (siehe Schritt 3) auf den Computer. Weitere Informationen finden Sie unter PerformancePoint-Dienste-DLLs in Entwicklungsszenarios.
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.
Fügen Sie dem Projekt die folgenden DLLs als Assemblyverweise hinzu:
Microsoft.PerformancePoint.Scorecards.Client.dll
Microsoft.SharePoint.dll (von Hilfsklassen verwendet)
Der Beispieleditor enthält ebenfalls Assemblyverweise auf System.Core.dll, System.Web.dll, System.Web.Services.dll und System.Xml.Linq.dll. Je nach Funktionalität Ihrer Erweiterung sind u. U. weitere Projektverweise erforderlich.
Fügen Sie dem Projekt die folgenden Klassen aus dem Beispiel hinzu. Der Editor verwendet diese Hilfsklassen für die Interaktion mit dem PerformancePoint Services-Repository und der Cachedatei:
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.
Erben Sie von der Basisklasse, die Ihre Editorimplementierung unterstützt. Da es sich beim Beispiel-Datenquellen-Editor um eine Webanwendung handelt, wird von der Page-Klasse geerbt. Andere Implementierungen können von Basisklassen wie z. B. der UserControl- oder WebPart-Klasse abgeleitet werden.
Nachdem Sie die Editorklasse erstellt und konfiguriert haben, müssen Sie die Funktionalität des Editors definieren.
So definieren Sie die Bearbeitungsfunktionalität
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.
Rufen Sie wie im folgenden Codebeispiel dargestellt die Parameter aus der Abfragezeichenfolge ab, und legen Sie sie als Werte für lokale Variablen fest:
// 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];
Informationen zu den Abfragezeichenfolgenparametern finden Sie unter Editoren für benutzerdefinierte PerformancePoint Services-Objekte.
Rufen Sie wie im folgenden Codebeispiel dargestellt das DataSourceRepositoryHelper-Objekt ab, das für Aufrufe an das Repository verwendet wird.
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);
Rufen Sie wie im folgenden Codebeispiel dargestellt den auszuführenden Vorgang (OpenItem oder CreateItem) aus der Abfragezeichenfolge ab, und rufen Sie dann die benutzerdefinierte Datenquelle ab, oder erstellen Sie sie.
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; }
Verwenden Sie die DataSourceRepositoryHelper.Get-Methode zum Abrufen der benutzerdefinierten Datenquelle.
Verwenden Sie zum Erstellen der benutzerdefinierten Datenquelle den DataSource()-Konstruktor, und definieren Sie dann die Eigenschaften Name und SubTypeId der Datenquelle. SubTypeId ist der eindeutige Bezeichner für die Datenquelle und muss mit dem subType-Attribut übereinstimmen, das Sie für die benutzerdefinierte Datenquelle in der PerformancePoint Services-Datei web.config angeben.
Hinweis Der Beispiel-Datenquellen-Editor enthält keine Logik zum Erstellen eines Datenquellenobjekts. Beispiele zum Erstellen eines benutzerdefinierten Objekts finden Sie unter Gewusst wie: Erstellen von Editoren für PerformancePoint Services-Berichte oder Gewusst wie: Erstellen von Editoren für PerformancePoint Services-Filter.
Hinweis Standardmäßig ist es den Benutzern nur möglich, benutzerdefinierte Objekte über den PerformancePoint Dashboard-Designer zu erstellen. Damit sie auch außerhalb von Dashboard-Designer benutzerdefinierte Objekte erstellen können, müssen Sie ein Menüelement hinzufügen, das vom Inhaltstyp im Repository eine CreateItem-Anforderung an den Editor sendet. Weitere Informationen finden Sie unter Editoren für benutzerdefinierte PerformancePoint Services-Objekte.
Der Beispiel-Datenquellen-Editor führt die Schritte 2 bis 5 in der Page_Load-Methode aus. Page_Load wird auch zum Initialisieren und Überprüfen von Variablen und Steuerelementen, zum Auffüllen von Steuerelementen sowie zum Speichern der Statusinformationen für die benutzerdefinierte Datenquelle und für Hilfsobjekte verwendet.
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, Description und Owner (Verantwortliche Person) eines benutzerdefinierten Objekts ändern und benutzerdefinierte Objekte direkt in Dashboard-Designer und im PerformancePoint Services-Repository löschen.
Rufen Sie den Datenquellenanbieter auf, um Spaltenzuordnungen zu definieren, falls dies noch nicht geschehen ist.
Der Beispiel-Datenquellen-Editor führt die Schritte 6 und 7 der 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.
Nächster Schritt: Nachdem Sie einen Datenquellen-Editor (einschließlich ggf. der zugehörigen Benutzeroberfläche) und Datenquellenanbieter erstellt haben, stellen Sie die Erweiterung wie unter Gewusst wie: Manuelles Registrieren von PerformancePoint-Dienste-Erweiterungen beschrieben bereit. Anweisungen zum Installieren und Konfigurieren der Beispiel-Datenquellenerweiterung finden Sie im Abschnitt "Installieren der Beispielobjekte für Berichte, Filter und Datenquellen" unter Codebeispiel: Benutzerdefinierte Objekte für Berichte, Filter und tabulierte Datenquellen.
Beispiel
Im folgenden Codebeispiel werden benutzerdefinierte tabulare Datenquellen im Repository abgerufen und aktualisiert sowie die Programmierlogik für die auf einer ASPX-Seite definierten Steuerelemente bereitgestellt.
Hinweis |
---|
Bevor Sie dieses Codebeispiel kompilieren können, müssen Sie die Entwicklungsumgebung wie unter So erstellen und konfigurieren Sie die Editorklasse 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
}
}
Code wird kompiliert
Bevor Sie dieses Codebeispiel kompilieren können, müssen Sie die Entwicklungsumgebung wie unter So erstellen und konfigurieren Sie die Editorklasse beschrieben konfigurieren.
Sicherheit
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 dazu, wie Sie eine Assembly mit einem starken Namen signieren und ein öffentliches/privates Schlüsselpaar erstellen, finden Sie unter How to: Create a Public/Private Key Pair.
Siehe auch
Aufgaben
Gewusst wie: Erstellen von Anbietern für tabularische Datenquellen von PerformancePoint Services
Konzepte
Editoren für benutzerdefinierte PerformancePoint Services-Objekte
Weitere Ressourcen
Erstellen von benutzerdefinierten Objekten für PerformancePoint Services
Codebeispiele für PerformancePoint Services in SharePoint Server 2010