Crear editores de fuentes de datos tabulares para PerformancePoint Services en SharePoint
Aprenda a crear el componente de edición de una extensión de fuente de datos tabulares personalizada para PerformancePoint Services.
¿Para qué sirven los editores de orígenes de datos personalizadosPerformancePoint Services?
En PerformancePoint Services, los editores de orígenes de datos personalizados permiten a los usuarios definir propiedades en orígenes de datos tabulares personalizados. Para más información sobre los requisitos y las funciones de los editores, vea Editores para objetos personalizados de PerformancePoint Services.
Los procedimientos y los ejemplos de código siguientes se han basado en la clase SampleDataSourceEditor del ejemplo de objetos personalizados. El editor es una aplicación web ligera que permite que los usuarios puedan modificar el nombre y la descripción del origen de datos, introducir símbolos del valor y especificar una dirección de servidor proxy y una ubicación del archivo de caché. Encontrará el código completo de la clase en Código de ejemplo: Recuperar y actualizar orígenes de datos tabulares personalizados.
Se recomienda usar el editor de ejemplo como plantilla. El ejemplo muestra cómo llamar a objetos en la API de PerformancePoint Services, proporciona objetos auxiliares que simplifican llamadas para operaciones de repositorio (como la creación y actualización de objetos) y muestra los procedimientos recomendados para el desarrollo de PerformancePoint Services.
Crear editores para orígenes de datos tabulares de PerformancePoint Services personalizados
Instale PerformancePoint Services o copie los DLL que la extensión usa (enumerados en el paso 3) en el equipo. Para obtener más información, vea ARCHIVOS DLL con bibliotecas de clases.
En Visual Studio, cree una biblioteca de clases de C#. Si ya ha creado una biblioteca de clases para su extensión, agregue una nueva clase de C#.
Debe firmar su DLL con un nombre seguro. Además, asegúrese de que todos los ensamblados a los que su DLL hace referencia tengan nombres seguros. Para obtener información sobre cómo firmar un ensamblado con un nombre seguro y cómo crear un par de claves pública y privada, vea How to: Create a public/private key pair.
Agregue las siguientes DLL como referencias de ensamblado al proyecto:
- Microsoft.PerformancePoint.Scorecards.Client.dll
- Microsoft.SharePoint.dll (usada por las clases auxiliares)
El editor de ejemplos también contiene referencias de ensamblado a System.Core.dll, System.Web.dll, System.Web.Services.dll y System.Xml.Linq.dll. Según la funcionalidad de la extensión, es posible que se necesiten otras referencias de proyecto.
Agregue las siguientes clases del ejemplo al proyecto. El editor usa estas clases de aplicaciones auxiliares para interactuar con el repositorio de PerformancePoint Services y el archivo de caché:
- ExtensionRepositoryHelper.cs
- DataSourceRepositoryHelper.cs
- SampleDSCacheHandler.cs
En la clase de editor, agregue una directiva using en el espacio de nombres Microsoft.PerformancePoint.Scorecards. Según la funcionalidad de la extensión, pueden requerirse otras directivas using.
Herede de la clase base que admite la implementación del editor. Dado que el editor de origen de datos de ejemplo es una aplicación web, hereda de la clase Page . Pueden derivar otras implementaciones de las clases base, como la clase UserControl o WebPart .
Declare variables para los controles que exponen las propiedades que desea que los usuarios vean o modifiquen. En primer lugar, el editor de origen de datos de ejemplo declara variables para los controles del servidor web que se definen en el componente de la interfaz de usuario, que es una página ASPX. El editor de ejemplo también define un control de botón que permite a los usuarios enviar los cambios. A continuación, el editor llama al método CreateChildControls() para que los controles estén disponibles en la página.
Nota:
[!NOTA] El editor define la lógica de programación independientemente de la interfaz de usuario. Las instrucciones para crear el componente de interfaz de usuario del editor están fuera del ámbito de esta documentación.
El editor de origen de datos de ejemplo realiza los pasos 8 a 11 en el método Page_Load. Page_Load también se usa para inicializar y validar variables y controles, rellenar controles y guardar la información de estado de los objetos auxiliares y el origen de datos personalizado.
Recupere los parámetros de la cadena de consulta y establézcalos como valores para las variables locales, como se muestra en el siguiente ejemplo de código.
// 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];
Nota:
Para obtener información sobre los parámetros de cadena de consulta, vea Editores para objetos de PerformancePoint Services personalizados.
Recupere el objeto DataSourceRepositoryHelper que se usa para realizar llamadas al repositorio, como se muestra en el siguiente ejemplo de código.
DataSourceRepositoryHelper = new DataSourceRepositoryHelper();
Establezca la ubicación del origen de datos en función del parámetro de cadena de consulta, como se muestra en el siguiente ejemplo de código.
RepositoryLocation repositoryDataSourceLocation = RepositoryLocation.CreateFromUriString(itemLocation);
Recupere la operación que desea realizar ( OpenItem o CreateItem) de la cadena de consulta y después recupere o cree el origen de datos personalizado.
- Para recuperar el origen de datos personalizado, use el método DataSourceRepositoryHelper.Get.
- Para crear el origen de datos personalizado, use el constructor DataSource() y después defina las propiedades Name y SubTypeId del origen de datos. SubTypeId es el identificador único del origen de datos y debe coincidir con el atributo subType especificado para el origen de datos personalizado en el archivo web.config de PerformancePoint Services.
Nota:
[!NOTA] El editor de origen de datos de ejemplo no incluye la lógica para crear un objeto de origen de datos. Para obtener ejemplos de cómo crear un objeto personalizado, vea Cómo: Crear editores de informes para PerformancePoint Services en SharePoint o Cómo: Crear editores de filtros para PerformancePoint Services en 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; }
Nota:
[!NOTA] De forma predeterminada, los usuarios solo pueden crear objetos personalizados desde el Diseñador de paneles de PerformancePoint. Para permitir que los usuarios creen un objeto personalizado fuera del Diseñador de paneles, debe agregar un elemento de menú que envíe una solicitud CreateItem al editor desde el tipo de contenido del repositorio. Para obtener más información, consulte Editores para objetos personalizados de PerformancePoint Services.
El editor de origen de datos de ejemplo realiza los pasos 12 y 13 en los métodos buttonOK_Click y CreateCacheFile. También se usa buttonOK_Click para llamar al método AreAllInputsValid para validar el contenido de los controles y para recuperar información de estado del origen de datos personalizado y el objeto auxiliar.
Actualice el origen de datos con los cambios definidos por el usuario. El editor de origen de datos de ejemplo llama al método DataSourceRepositoryHelper.Update para actualizar las propiedades Name , Description y CustomData del objeto de origen de datos en el repositorio. Puede usar CustomData para almacenar una cadena u objeto serializados. El editor de ejemplo lo usa para almacenar símbolos del valor definidos por el usuario, la ubicación del archivo de caché que almacena valores de índice de cotizaciones y la dirección del servidor proxy.
Nota:
Los usuarios pueden editar las propiedades Name , Description y Owner (Person Responsible) de un objeto personalizado y eliminar objetos personalizados directamente desde el Diseñador de paneles y el repositorio de PerformancePoint Services.
Llame al proveedor de orígenes de datos para definir las asignaciones de columnas si aún no están definidas.
Ejemplo de código: Recuperación y actualización de orígenes de datos tabulares de PerformancePoint Services personalizados en SharePoint
El siguiente ejemplo de código recupera y actualiza orígenes de datos tabulares personalizados. Este código ha sido extraído de la clase subyacente del código del editor, el cual proporciona la lógica de programación para los controles definidos en una página ASPX.
Antes de compilar este ejemplo de código, debe configurar su entorno de desarrollo tal y como se describe en Crear y configurar la clase de editor para un editor de origen de datos tabular en PerformancePoint Services.
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
}
}
Pasos siguientes
Después de crear un editor de origen de datos (incluida su interfaz de usuario, si es necesario) y un proveedor de orígenes de datos, implemente la extensión como se describe en How to: Manually Register PerformancePoint Services Extensions.