Primer vistazo

Herramientas de Visual Studio 2010 para desarrollo de SharePoint

Steve Fox

El desarrollo de SharePoint ha sido un poco misterioso para muchos desarrolladores, que han sentido que el desarrollo para la plataforma fue complicado y estuvo fuera de su alcance. La comunidad de desarrolladores también se ha visto dividida sobre qué conjunto de herramientas usar. Por ejemplo, algunos desarrolladores utilizaron una combinación de bibliotecas de clases, carpetas de proyectos manuales con archivos de configuración XML y eventos de salida posteriores a la creación para generar características y soluciones para SharePoint. Otros desarrolladores utilizaron STSDEV, una herramienta de la comunidad, o extensiones de Visual Studio para Windows SharePoint Services (VSeWSS) para crear otras aplicaciones y soluciones, e implementarlas en SharePoint. En otras palabras, los desarrolladores podrían seguir varias rutas para implementar paquetes de características y soluciones en SharePoint. A pesar de los desafíos, la comunidad de desarrolladores de SharePoint ha aumentado a un número importante (aproximadamente 600.000) y sigue creciendo. A futuro, Visual Studio 2010 ofrecerá a los desarrolladores un gran acceso al desarrollo de SharePoint con las herramientas nuevas que vendrán con el producto.

SharePoint 2010 es un avance importante como plataforma de desarrollo, no sólo por el conjunto enriquecido de características que admite, sino porque además se realizaron importantes inversiones en el paquete de herramientas diseñadas para lograr que el proceso de desarrollo sea más productivo y más accesible para los desarrolladores de todos los niveles de habilidades. Las dos herramientas centrales para desarrolladores para SharePoint 2010 son SharePoint Designer 2010 y Visual Studio 2010. (El conjunto de herramientas complementarias es el conjunto Expression.) Este artículo entrega un primer vistazo al desarrollo de SharePoint 2010, al presentarle las herramientas de SharePoint en Visual Studio 2010 (incluida una mirada a las plantillas de proyecto nuevas) y demostrarle cómo crear e implementar un ejemplo de elemento web visual.

Herramientas de SharePoint en Visual Studio 2010

Vale la pena mencionar varias áreas para desarrolladores de SharePoint en Visual Studio 2010. Primero, obtiene plantillas de proyecto de SharePoint que vienen con el producto, de manera que puede comenzar inmediatamente el desarrollo de soluciones. Segundo, las herramientas se estandarizaron según el paquete de Windows SharePoint (WSP), de manera que cuando importa o implementa una solución en SharePoint, Visual Studio la trata como un paquete de soluciones. Tercero, algunas fantásticas características de implementación y empaquetado, como configuraciones de retiro de soluciones e implementación personalizada, vienen con las herramientas de SharePoint en Visual Studio 2010. Y, por último, el nuevo SharePoint Explorer proporciona una vista de los artefactos nativos y personalizados (por ejemplo, listas y flujos de trabajo) que existen en el servidor de SharePoint. Desde luego, ésta es una breve lista de las características que representan una extensión importante de un conjunto de herramientas de Visual Studio diseñadas para incorporarse a una comunidad y hacerles la vida más fácil a los desarrolladores.

También vale la pena mencionar un par de mejoras de SharePoint 2010, que sin duda se pueden utilizar en el contexto de Visual Studio 2010. Por ejemplo, el nuevo modelo de objeto de cliente le otorga acceso a objetos de SharePoint a través de una DLL a la que se hace referencia en lugar de llamadas de servicios web. (En SharePoint 2007, obtiene acceso a los datos de la lista de SharePoint, por ejemplo, al utilizar un servicio web de ASP.NET.) Además, LINQ para SharePoint suma la eficacia de LINQ a SharePoint, al permitirle tratar listas, por ejemplo, como objetos de establecimiento inflexible de tipos. Además, Silverlight (sobre todo en combinación con el modelo de objeto de cliente) se admite de manera nativa en SharePoint 2010: se acabaron los problemas con web.config para comenzar con este desarrollo. Además, las soluciones con recinto también ofrecen una manera de crear elementos web de SharePoint e implementarlos en un sitio sin necesidad de intervención administrativa, es decir, puede implementar un elemento web en un sitio de SharePoint y ejecutarlo en el contexto de ese sitio en una instancia local de SharePoint o en la nube mediante la versión hospedada de SharePoint. Por último, las listas de datos externas hacen de la interacción con sistemas de línea de negocio un proceso de lectura/escritura y, aunque aparentemente pequeño, éste es un enorme avance dada la compatibilidad de las herramientas que le permite crear integraciones de línea de negocio de manera rápida y eficiente. Para cada una de estas innovaciones en SharePoint 2010, Visual Studio 2010 proporciona algún grado de compatibilidad, a través de plantillas de proyecto o API, para desarrolladores profesionales. Si hay un momento para aprovechar el desarrollo de SharePoint, es ahora.

Desarrollo de un proyecto de elemento web visual

Uno de los artefactos más comunes que los desarrolladores crean e implementan en SharePoint es el elemento web. Tiene sentido si consideramos que los elementos web son uno de los bloques de creación principales para SharePoint. Dado que SharePoint se crea sobre ASP.NET, el elemento web hereda características clave de la arquitectura del elemento web de ASP.NET.

Una de las plantillas de proyecto nuevas en Visual Studio 2010 es la plantilla de proyecto del elemento web visual, la cual permite que los desarrolladores diseñen visualmente un elemento web que pueda implementarse en SharePoint. Si no conoce SharePoint, ésta es una gran manera de comenzar a crear aplicaciones personalizadas para SharePoint 2010. El elemento web visual que demostraré posee un código independiente que calcula los costos del producto y muestra la información en una IU del elemento web simple.


Figura 1 Plantillas de proyecto nuevas de SharePoint


Figura 2 Visión del diseñador para un elemento web visual

Asegúrese de tener la versión beta 2 de Visual Studio 2010 y la versión beta 2 de SharePoint 2010 instaladas en Windows Server 2008 de 64 bits. Abra Visual Studio 2010, haga clic en Archivo, Proyecto nuevo y navegue hasta el nodo SharePoint en la sección Plantillas instaladas. La Figura 1 muestra los distintos tipos de plantillas de proyecto disponibles. Por ejemplo, la plantilla de proyecto VSeWSS de importación proporciona una ruta de actualización de sus proyectos VSeWSS actuales; las plantillas de flujo de trabajo le permiten crear e implementar proyectos de flujo de trabajo en SharePoint; la plantilla de definición de sitio proporciona infraestructura a nivel de sitio que puede incorporar e implementar; y el paquete de solución de importación de SharePoint es la plantilla que le permite importar WSP para volver a implementarlos en una instancia de servidor local. Para este recorrido, seleccione la plantilla de proyecto de elemento web visual, proporcione un nombre (por ejemplo, SampleWebPartProject) y una ubicación para su proyecto, y haga clic en Aceptar.

Después de crear un proyecto, Visual Studio 2010 creará varios archivos predeterminados. Amplíe los nodos del proyecto en el Explorador de soluciones para ver los archivos. Los archivos clave con los que trabajará en este artículo están en el nodo SampleWebPartProject. Tenga en cuenta que el elemento web visual predeterminado se denomina VisualWebPart1. Para modificarlo, haga clic con el botón secundario en el nodo VisualWebPart1 en el Explorador de soluciones, seleccione Cambiar nombre y escriba otro nombre para su elemento web.

Tenga en cuenta en el Explorador de soluciones la presencia de los nodos Características y Paquete. Éstas corresponden a partes de infraestructura nuevas en Visual Studio 2010 que empaquetan una solución de SharePoint mediante una característica de SharePoint. Para desarrolladores que no conocen SharePoint, una característica organiza sus aplicaciones de una manera que SharePoint comprende. Por ejemplo, se pueden implementar características en SharePoint en el sitio o a nivel de Web. Una característica se estructura a través de un conjunto de archivos de configuración XML y además hace referencia (dependiendo del nivel de seguridad para la aplicación) al ensamblado desde la caché de ensamblado global (GAC). Específicamente, cada característica posee su propia carpeta en la jerarquía de carpetas de SharePoint y los archivos de configuración existen dentro de esa carpeta y proporcionan los metadatos necesarios para la característica. El paquete contiene características y otros activos, y se usa cuando implementa soluciones en SharePoint. El paquete también está donde se determina la ubicación de la implementación del ensamblado. Visual Studio 2010 presenta un diseñador de paquetes, que facilita las tareas de visualización y administración de paquetes. Si hace doble clic en el nodo Paquete, el diseñador se abre. El diseñador proporciona la capacidad para que agregue y elimine características del paquete de implementación. Este diseñador representa un paso importante para ayudar a los desarrolladores a dar forma a sus soluciones de SharePoint a través de la suma de características.

Retroceda a la vista del Explorador de soluciones, haga clic con el botón secundario en el archivo ProductInfoUserControl.ascx y escoja Vista en Diseñador. Esto abre una vista en la cual puede arrastrar y soltar controles del cuadro de herramientas en la superficie de diseño del elemento web. Verá tres vistas: Diseño, División y Código. En este ejemplo, agregué (escribiendo) un título y algunos controles, incluidos cuadros de texto y un botón para calcular el costo del producto. También escribí etiquetas para los controles que se agregaron a la página (consulte la Figura 2).

Después de completar la disposición del elemento web visual, puede agregar controladores de evento para el botón. Pero antes de hacer eso, echemos un vistazo rápido al código fuente para el elemento web visual. Como puede ver a partir del extracto de código en la Figura 3, Visual Studio agrega cierto estilo automático a la IU en la forma de sintaxis CSS. También puede ver los controles reales (y en el caso de la lista desplegable, la colección de elementos) que conforman la IU. Tenga en cuenta que por motivos de brevedad, eliminé las directivas que se generan de forma automática y se incluyen en la parte superior de la fuente.

Para agregar controladores de evento al elemento web, haga doble clic en el botón. Esto lo lleva al código subyacente. También agrega un evento onClick al diseño de control ASCX. Por ejemplo, en la Figura 3 tenga en cuenta el evento onclick="btnCalcPrice_Click" que se incluye dentro de btnCalcPrice. El código subyacente, que aparece en la Figura 4, contiene cierto código simple que le permite calcular el precio del producto que se selecciona en el cuadro de lista. Las partes clave del código son las variables a nivel de clase (las dobles), que representan la manera extendida en que solía calcular el costo del producto; la colección de la Lista de productos (que contiene varios objetos producto que se agregan al cuadro de lista); y el evento btnCalcPrice_Click. Cuando la página se carga en SharePoint, el código llama al método generateProductList, que llena el cuadro de lista. El evento btnCalcPrice_Click entonces calcula el costo de un producto específico, dependiendo de lo que seleccionó el usuario, y muestra la información en el cuadro de lista en la IU.

Figura 3 Código fuente para SalaryCalcWebPartUserControl.ascx

<style type="text/css">
.style1
{
font-family: Calibri;
font-size: medium;
font-weight: bold;
}
.style2
{
font-family: Calibri;
font-size: small;
font-weight: bold;
}
</style>
<p class="style1">
Product Catalog</p>
<p class="style2">
Product:  
<asp:DropDownList ID="dropdwnProducts" 
runat="server" Height="20px"
style="margin-left: 21px" Width="200px">
<asp:ListItem>Helmet</asp:ListItem>
<asp:ListItem>Stick</asp:ListItem>
<asp:ListItem>Skates</asp:ListItem>
<asp:ListItem>Elbow Pads</asp:ListItem>
<asp:ListItem>Kneepads</asp:ListItem>
</asp:DropDownList>
</p>
<p class="style2">
Description: <asp:TextBox ID="txtbxDescription" runat="server"
Width=”200px” Enabled=”False”></asp:TextBox>
</p>
<p class="style2">
SKU:
<asp:TextBox ID="txtbxSKU" runat="server" style="margin-left: 48px"
Width="200px" Enabled="False"></asp:TextBox>
</p>
<p class="style2">
Price:<asp:TextBox ID="txtbxPrice" runat="server"
style="margin-left: 48px"
Width="200px" Enabled="False"></asp:TextBox>
</p>
<p class="style2">
Quantity:
<asp:TextBox ID="txtbxQuantity" runat="server" 
Width="200px" Enabled="False"></asp:TextBox>
</p>
<p class="style1">
<asp:Button ID="btnCalcPrice" runat="server"
onclick="btnCalcPrice_Click"
Text="Calc." />
</p>

Cuando un usuario hace clic en el botón, el elemento web realiza una devolución para ejecutar el evento (en este caso, calcular el costo del producto). Lo que es probablemente más interesante que el código en la Figura 4, el cual en esencia es bastante simple, es cómo el elemento web expone este código en el verdadero elemento web. Considerando que lo que hemos hecho es crear un control de usuario ASP para nuestro elemento web que incluye una máscara y un código subyacente, la estructura del proyecto todavía tiene el verdadero elemento web que debe exponer este control. Para hacer esto, Visual Studio crea una cadena denominada _ascxPath, la cual representa la ruta al control de usuario ASCX ubicado dentro de la jerarquía de carpetas de SharePoint 2010. Fíjese también que en el método CreateChildControls, se crea una instancia de un control y se configura en la ruta al control de usuario (mediante el método LoadControl). Luego se agrega a la colección de controles mediante el método Agregar. Esto permite que el elemento web exponga el control de usuario ASP dentro del elemento web en SharePoint. La Figura 5 muestra el código.

Figura 4 Código fuente para ProductInfoUserControl.ascx.cs

using System;
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Collections.Generic;
using System.Data;
namespace SampleWebPartProject.ProductInfo
{
public partial class ProductInfoUserControl : UserControl
{
double tax = .11;
double totalCost = 0.0;
List<Products> lstOfProducts = new List<Products>();
protected void Page_Load(object sender, EventArgs e)
{
generateProductList();
}
private void generateProductList()
{
lstOfProducts.Add(new Products()
{ strName = "Helmet", strDescr = "Hockey helmet.", strSKU =
"KLSONHELMT1224", dblPrice = 59.00, intQuantity = 28 });
lstOfProducts.Add(new Products()
{ strName = "Skates", strDescr = "Hockey skates.", strSKU =
"SKATWOKSH0965", dblPrice = 438.00, intQuantity = 88 });
lstOfProducts.Add(new Products()
{ strName = "Stick", strDescr = "Composite hockey stick.",
strSKU = "STIK82910JJKS", dblPrice = 189.99, intQuantity =
35 });
lstOfProducts.Add(new Products()
{ strName = "Elbow Pads", strDescr = "Hockey elbow pads.",
strSKU = "ELBOP563215NN", dblPrice = 34.00, intQuantity =
12 });
lstOfProducts.Add(new Products()
{ strName = "Knee Pads", strDescr = "Hockey knee pads.",
strSKU = "KPDS7827NNJS1", dblPrice = 47.99, intQuantity =
44 });
}
protected void btnCalcPrice_Click(object sender, EventArgs e)
{
double dblCost = 0;
string strPrice = "";
if (dropdwnProducts.SelectedValue == "Helmet")
{
dblCost = lstOfProducts[0].dblPrice;
totalCost = dblCost + (dblCost * tax);
System.Math.Round(totalCost, 2);
strPrice = "$" + totalCost.ToString();
txtbxDescription.Text = lstOfProducts[0].strDescr.
ToString();
txtbxSKU.Text = lstOfProducts[0].strSKU.ToString();
txtbxPrice.Text = strPrice;
txtbxQuantity.Text = lstOfProducts[0].intQuantity.
ToString();
}
else if (dropdwnProducts.SelectedValue == "Skates")
{
dblCost = lstOfProducts[1].dblPrice;
totalCost = dblCost + (dblCost * tax);
System.Math.Round(totalCost, 2);
strPrice = "$" + totalCost.ToString();
txtbxDescription.Text = lstOfProducts[1].strDescr.
ToString();
txtbxSKU.Text = lstOfProducts[1].strSKU.ToString();
txtbxPrice.Text = strPrice;
txtbxQuantity.Text = lstOfProducts[1].intQuantity.
ToString();
}
else if (dropdwnProducts.SelectedValue == "Stick")
{
dblCost = lstOfProducts[2].dblPrice;
totalCost = dblCost + (dblCost * tax);
System.Math.Round(totalCost, 2);
strPrice = "$" + totalCost.ToString();
txtbxDescription.Text = lstOfProducts[2].strDescr.
ToString();
txtbxSKU.Text = lstOfProducts[2].strSKU.ToString();
txtbxPrice.Text = strPrice;
txtbxQuantity.Text = lstOfProducts[2].intQuantity.
ToString();
}
else if (dropdwnProducts.SelectedValue == "Elbow Pads")
{
dblCost = lstOfProducts[3].dblPrice;
totalCost = dblCost + (dblCost * tax);
System.Math.Round(totalCost, 2);
strPrice = "$" + totalCost.ToString();
txtbxDescription.Text = lstOfProducts[3].strDescr.
ToString();
txtbxSKU.Text = lstOfProducts[3].strSKU.ToString();
txtbxPrice.Text = strPrice;
txtbxQuantity.Text = lstOfProducts[3].intQuantity.
ToString();
}
else if (dropdwnProducts.SelectedValue == "Knee Pads")
{
dblCost = lstOfProducts[4].dblPrice;
totalCost = dblCost + (dblCost * tax);
System.Math.Round(totalCost, 2);
strPrice = "$" + totalCost.ToString();
txtbxDescription.Text = lstOfProducts[4].strDescr.
ToString();
txtbxSKU.Text = lstOfProducts[4].strSKU.ToString();
txtbxPrice.Text = strPrice;
txtbxQuantity.Text = lstOfProducts[4].intQuantity.
ToString();
}
}
}
}

Figura 5 Código fuente para ProductInfo.cs

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
namespace SampleWebPartProject.ProductInfo
{
public class ProductInfo : WebPart
{
private const string _ascxPath =
@"~/CONTROLTEMPLATES/SampleWebPartProject/ProductInfo/" +
@"ProductInfoUserControl.ascx";
public ProductInfo()
{
}
protected override void CreateChildControls()
{
Control control = this.Page.LoadControl(_ascxPath);
Controls.Add(control);
base.CreateChildControls();
}
protected override void Render(HtmlTextWriter writer)
{
base.RenderContents(writer);
}
}
}

Figura 6 Archivo XML ProductInfo.webpart

<?xml version="1.0" encoding="utf-8"?>
<webParts>
<webPart xmlns="https://schemas.microsoft.com/WebPart/v3">
<metaData>
<type name="SampleWebPartProject.ProductInfo.ProductInfo,
SampleWebPartProject, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=db3a9f914308c42a" />
<importErrorMessage>
$Resources:core,ImportErrorMessage;
</importErrorMessage>
</metaData>
<data>
<properties>
<property name="Title" type="string">
Product Info Web Part</property>
<property name="Description" type="string">Provides some
information about hockey products.</property>
</properties>
</data>
</webPart>
</webParts>

Ahora que creó el elemento web visual, puede implementarlo en su servidor de SharePoint. Cuando creó el proyecto, lo configuró para asociarse con una instancia de servidor particular. La implicación aquí es que existe cierto trabajo de fusión programático que reúne el código que acaba de escribir con el servidor de SharePoint. Si revisa los archivos en el Explorador de soluciones, verá un número de archivos XML que ayudan en esta integración. Por ejemplo, el archivo Feature.xml (vea el siguiente código) proporciona una definición de la característica. Puede ver en el XML que el archivo hace referencia a un par de otros archivos XML que también proporcionan información específica acerca del elemento web. Acá puede ver que se hace referencia a Elements.xml y ProductInfo.webpart:

<?xml version="1.0" encoding="utf-8"?>
<Feature xmlns="https://schemas.microsoft.com/sharepoint/" 
Id="416172c1-cfa7-4d7a-93ba-fe093b037fab" 
ImageUrl="" Scope="Site" Title="SampleWebPartProject Feature1">
  <ElementManifests>
    <ElementManifest Location="ProductInfo\Elements.xml" />
    <ElementFile Location="ProductInfo\ProductInfo.webpart" />
  </ElementManifests>

Elements.xml proporciona información acerca de los ensamblados principales que se incluyen en la característica y ProductInfo.webpart define metadatos acerca del elemento web, como su título y descripción. Por ejemplo, la Figura 6 muestra las propiedades predeterminadas de Título y Descripción. Puede actualizar estas propiedades para asegurarse de que los metadatos del elemento web expuestos en la Galería de elementos web sean intuitivos y significativos. En el caso de este elemento web, probablemente desee corregir el título a Elemento web de información de producto y que la descripción diga algo como, “elemento web que proporciona precios e información calculados para el producto”.


Figura 7 Elemento web en la página del elemento web

Existen otros archivos de configuración XML y si no conoce el desarrollo de SharePoint, lo animo a revisar cada uno de los archivos del proyecto para comprender mejor su propósito. Ahora pasemos a implementar el elemento web en su servidor de SharePoint.

Implementación del proyecto de elemento web visual

Antes de SharePoint 2010, se usaba Stsadm, una herramienta de administración controlada por una línea de comandos, para implementar aplicaciones en SharePoint. Esto ya no es necesario con Visual Studio 2010 (y con la introducción de Window PowerShell, pero éste es un tema digno de su propio artículo). Como su proyecto ya tiene una relación con su servidor de SharePoint y la asociación tiene un nivel de seguridad definido, sólo necesita hacer clic con el botón secundario en el proyecto y seleccionar Crear, asegurarse de que se cree la solución y hacer clic con el botón secundario y seleccionar Implementar. Desde luego, usar la tecla F5 también funcionará al depurar sus soluciones de SharePoint. Al hacer esto, la experiencia de depuración incluye pasos como asociación al proceso adecuado y restablecimiento de IIS.

Después de implementar correctamente el elemento web, tiene que abrir su sitio de SharePoint y crear una página nueva del elemento web. Si hizo clic en F5 para depurar la aplicación, se invoca la página Crear elemento web de manera predeterminada. De lo contrario, haga clic en Ver todo el contenido del sitio y luego en Crear. Haga clic en la opción Página del elemento web y proporcione la información que se solicita acerca de esa página del elemento web en particular. Por ejemplo, proporcione un nombre y una plantilla de diseño para la página. Después de ingresar esta información, haga clic en Crear y SharePoint crea su página del elemento web.

Ahora tiene que agregar el elemento web visual que creó e implementó en el servidor. Para hacer esto, navegue hasta la página del elemento web, haga clic en Acciones del sitio y haga clic en Editar página. Haga clic en la zona del elemento web en la cual desea colocar el elemento web visual, haga clic en la ficha Insertar y en Elemento web.

Después de hacer esto, SharePoint expone varias categorías de elemento web que puede explorar para seleccionar un elemento web específico para agregar a la zona de elemento web que seleccionó en la página. Navegue hasta la categoría Personalizar y, en el panel Elementos web, verá el elemento web visual que creó e implementó. Si prosiguió con el código de este artículo, haga clic en el elemento web ProductInfo y luego en el botón Agregar.

El elemento web ahora se agrega a la zona Elemento web en la página del elemento web, como se muestra en la Figura 7. En este punto, puede configurar las opciones de elemento web en el panel Herramientas o simplemente puede aceptar las opciones predeterminadas y hacer clic en Detener edición.

Participe del desarrollo de SharePoint

Para algunos desarrolladores de SharePoint, Visual Studio 2010 proporciona no sólo un conjunto de herramientas nativas, sino además una oportunidad increíble de participar del desarrollo de SharePoint. Lo animo a que revise estas herramientas. Éstas son algunas fantásticas opciones para desarrolladores a quienes les gusta tener control sobre su código y para aquellos a quienes les agrada la experiencia de diseño para crear e implementar grandes soluciones en SharePoint.

Steve Fox es técnico senior integrante del equipo de evangelización de plataformas y desarrolladores en Microsoft. Pasa la mayor parte del tiempo trabajando con clientes en el desarrollo de Office y SharePoint. Fox ha publicado varios libros y artículos, y es orador regular en conferencias de desarrolladores en todo el mundo.