SharePoint Online

Colaboración basada en la nube con SharePoint Online

Chris Mayo

Descargar el ejemplo de código

Con el lanzamiento de Office 365, Microsoft presentará la siguiente versión de Microsoft Online Services, un servicio de colaboración y comunicación basado en la nube y en SharePoint 2010, Exchange 2010 y Lync Server 2010. Office 365, el cual actualmente está en beta, proporcionará SharePoint, Exchange y Lync como una oferta de Software como servicio (SaaS, Software as a Service), hospedados en centros de datos en nube administrados por Microsoft.

SharePoint Online, la versión en la nube de SharePoint 2010, proporcionará a los usuarios muchas de las características de SharePoint 2010, pero sin la necesidad de administrar el hardware o software necesarios para una solución escalable y segura. En este artículo, entregaré una introducción general sobre las similitudes y diferencias del desarrollo en SharePoint 2010 respecto a la compilación de soluciones que se ejecutan en SharePoint Online.

Con el siguiente lanzamiento de SharePoint Online, los desarrolladores de SharePoint podrán desarrollar soluciones de colaboración usando las mismas competencias y herramientas que usaron en el desarrollo de SharePoint 2010, lo que incluye Visual Studio 2010, SharePoint Designer 2010, C# o Visual Basic y las API y SDK de SharePoint. Existen también muchas similitudes entre el desarrollo para SharePoint local y para aquel en la nube, pero también existen varias diferencias significativas que tendrán impacto en la compilación de soluciones.

Comprender estas diferencias le ayudará a saber cuáles soluciones se pueden crear para su ejecución en SharePoint Online y cómo desarrollarlas.

Similitudes de personalización de SharePoint Online

Al desarrollar en SharePoint 2010, se puede personalizar SharePoint mediante el explorador, SharePoint Designer 2010 y a través de la compilación de soluciones mediante Visual Studio 2010. Con SharePoint Online, la personalización con el explorador y con SharePoint Designer 2010 se hace de forma casi idéntica a como se hace en SharePoint 2010 (considerando las diferencias de características que se mencionan en la siguiente sección). El desarrollo de soluciones de SharePoint Online mediante Visual Studio 2010 también es, a grandes rasgos, el mismo. El desarrollo se realiza en Visual Studio 2010 frente a una instancia local de SharePoint 2010 (el cual se ejecuta localmente en Windows 7, Windows Server 2008 R2 o en una máquina virtual o VM), lo que permite sacar partido de la experiencia unificada de depuración para el desarrollo iterativo. Cuando se completa el desarrollo, la solución se carga a SharePoint Online usando la misma Galería de soluciones que se proporcionó en SharePoint 2010.

Diferencias clave en la personalización de SharePoint Online

Pese a que SharePoint Online está basado en SharePoint 2010, existen ciertas diferencias clave que se deben tomar en cuenta en el momento de desarrollar soluciones que se ejecutarán en este último. Primero: SharePoint Online sólo es compatible con soluciones para sitio y para web. Se ejecuta en una nube de varios inquilinos, donde se ejecutan arrendamientos múltiples en una infraestructura de centro de datos compartidos, de manera que es razonable que las soluciones de ámbito de granja (donde se activa una característica a toda la granja) no sean compatibles. Igualmente, en SharePoint Online, el nivel más alto de acceso al arrendamiento de SharePoint es en el nivel de colección de sitio, de manera que las características con ámbito de aplicación web (donde una característica se ejecuta en cada sitio web de una aplicación web) tampoco son compatibles.

Segundo: SharePoint Online sólo es compatible con las soluciones de confianza parcial. Tampoco es compatible con las soluciones de confianza plena, donde su solución tendría acceso más allá del nivel de colección de sitio o se le otorgaría permiso para que ejecute privilegios de nivel de administrador en la granja.

Por último, aunque SharePoint Online está basado en SharePoint 2010, no tiene una paridad 100 por ciento equivalente con su contraparte local. Para ver una comparación completa de cada una de las características de SharePoint 2010 y SharePoint Online, consulte la descripción de servicio de Microsoft SharePoint Online beta, disponible en la página de Descripción del servicio Office 365 beta en bit.ly/bBckol.

La lista comparativa de cada una de las características muestra que la mayor parte de las características de personalización de SharePoint son compatibles. La falta de compatibilidad para los servicios de conectividad empresarial (BCS), listas externas y la capacidad de llamar a servicios web externos a SharePoint Online (la cual no es compatible en soluciones de confianza parcial) tendrá un impacto significativo en la creación de soluciones que se ejecutan en SharePoint Online. Por otra parte, está planeado brindar compatibilidad con BCS en lanzamientos futuros.

Con estas similitudes y diferencias en mente, observemos algunos ejemplos de los tipos de soluciones que se pueden compilar para ser ejecutados en SharePoint Online, lo que incluye soluciones de recinto de seguridad y el modelo de objeto (OM) del cliente de SharePoint. Otros tipos de soluciones, como la automatización de procesos empresariales mediante soluciones declarativas de flujo de trabajo, se cubrirán en artículos futuros.

Desarrollo para SharePoint Online con soluciones de recinto de seguridad

A partir de la información proporcionada en la sección pasada, sabrá que las soluciones de SharePoint Online se deben enfocar a características de sitio o de web, están restringidas a datos en la colección de seguridad y se deben ejecutar con confianza parcial. El desarrollo de soluciones ejecutadas como soluciones de recinto de seguridad cumple todos esos criterios, al mismo tiempo que permite que los administradores de SharePoint Online implementen fácilmente las soluciones al cargarlas directamente a la Galería de soluciones.

Visual Studio 2010 proporciona una excelente compatibilidad para soluciones de recinto de seguridad, lo que incluye compatibilidad con plantillas de proyecto y plantillas de elemento de proyecto, el Asistente de personalización de SharePoint para la creación de nuevos proyectos como soluciones de recinto de seguridad, compatibilidad con IntelliSense para las API de SharePoint enfocadas a colecciones de sitio y compatibilidad con depuración y empaque. Para empezar a compilar una solución de SharePoint Online, deberá desarrollar y depurar la solución localmente frente a SharePoint 2010. Necesitará Windows 7 de 64 bits o Windows Server 2008 R2 con SharePoint 2010 y Visual Studio 2010 instalado. Otra manera extraordinaria de comenzar es usar 2010 Information Worker Demonstration and Evaluation Virtual Machine (RTM), el cual proporciona un entorno de desarrollo de SharePoint 2010 virtualizado (descárguelo desde bit.ly/ezfe2Y). También recomiendo las Power Tools de SharePoint para Visual Studio 2010 (bit.ly/azq882), las cuales brindan compatibilidad en tiempo de compilación para el recinto de seguridad y una plantilla de elemento de proyecto de elemento web visual en recinto de seguridad.

En los ejemplos de este artículo, compilaré una solución en un sencillo escenario donde se debe proporcionar a los empleados de la empresa ficticia Contoso Corp. la habilidad de solicitar adquisiciones que no son compatibles con el sistema de compra. Para comenzar, crearé una colección de sitio y un sitio en el entorno de desarrollo local de SharePoint 2010. Usaré las VM mencionadas anteriormente, de manera que cree a http://o365dpe.contoso.com/sites/spomsdnmag/purchasing. Mi primera solución implementará la lista usada para seguir estas adquisiciones no estándar. Abriré Visual Studio 2010, seleccionaré File | New Project (Archivo | Nuevo proyecto) y, en el cuadro de diálogo New Project (Proyecto nuevo), seleccionaré Empty SharePoint Project (Proyecto de SharePoint vacío). Denominaré al proyecto PurchasingMgr.

En el diálogo del Asistente de personalización de SharePoint, donde dice “What local site ...” (“¿Cuál sitio local ...?”), escribiré la URL de mi sitio, http://o365dpe.contoso.com/sites/spomsdnmag/Purchasing/, seleccionaré “Deploy as a sandboxed solution” (“Implementar como una solución de recinto de seguridad”) y haré clic en Finish (Finalizar), como se indica en la figura 1.

image: Specify the Site and Trust Level for PurchasingMgr

Figura 1 Especificación del sitio y del nivel de confianza de PurchasingMgr

A continuación, seleccionaré el proyecto PurchasingMgr en el Explorador de soluciones, haré clic con el botón secundario y seleccionaré Add | New Item (Agregar | Nuevo elemento). En el cuadro de diálogo Agregar nuevo elemento, seleccionaré SharePoint 2010 en el nodo Plantillas instaladas para las plantillas de elemento de SharePoint compatibles. No todas estas plantillas son compatibles con las soluciones de recinto de prueba, por lo tanto ocurre lo mismo en SharePoint Online. La figura 2 muestra las plantillas de elemento compatibles con las soluciones de recinto de seguridad.

Figura 2 Plantillas de elemento compatibles con las soluciones de recinto de seguridad

Plantilla de elemento ¿Es compatible con recinto de seguridad? Notas
Elemento web visual No Necesita la instalación de un archivo ASCX en servidores de SharePoint
Elemento visual web (de recinto de seguridad) Proporcionado con la instalación de Power Tools de SharePoint para Visual Studio 2010
Elemento web  
Flujo de trabajo secuencial No Necesita la implementación de una solución de flujo de trabajo como solución de granja
Flujo de trabajo de equipo de estado No Necesita la implementación de una solución de flujo de trabajo como solución de granja
Modelo de conectividad a datos empresariales No Necesita la implementación de una solución BCS como solución de confianza plena. La característica no es compatible con SharePoint Online
Página de aplicación No Necesita la implementación de una página ASPX en SharePoint Server
Receptor de eventos  
Módulo  
Tipo de contenido  
Definiciones de lista de tipo de contenido  
Definición de lista  
Instancia de lista  
Elemento vacío  
Control de usuario No Necesita la instalación de un archivo ASCX en servidores de SharePoint

Para compilar mi lista, definiré las columnas de sitio y el tipo de contenido de la lista al seleccionar la plantilla de elemento de tipo de contenido y le daré el nombre NonStandBusPurchaseRequestsCT.

En el Asistente de personalización de SharePoint, seleccionaré Item como el tipo de contenido base y haré clic en Finish. El tipo de contenido tendrá una columna Title (Título), otra llamada Description (Descripción) y otra más llamada Price (Precio), que definiré declarativamente mediante el reemplazo de los contenidos de Elements.xml creados con el XML de la figura 3.

Figura 3 Definición de NonStandBusPurchaseRequestsCT mediante Elements.xml

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="https://schemas.microsoft.com/sharepoint/">

  <Field SourceID="https://schemas.microsoft.com/sharepoint/v3"
    ID="{A74E67E5-8905-4280-90C9-DEBFFC30D43D}"
    Name="RequestDescription"
    DisplayName="Description"
    Group="Purchasing Manager Custom Columns"
    Type="Note"
    DisplaceOnUpgrade="TRUE" />
  <Field SourceID="https://schemas.microsoft.com/sharepoint/v3"
    ID="{CB5054F5-0C60-4DBE-94D2-CEFBFB793C7F}"
    Name="Price"
    DisplayName="Price"
    Group="Purchasing Manager Custom Columns"
    Type="Currency"
    DisplaceOnUpgrade="TRUE" />

  <!-- Parent ContentType: Item (0x01) -->
  <ContentType ID="0x010078a81c8413f54917856495e56e7c09ed"
    Name="Purchasing Manager - Non-Standard Business Purchase Requests Content Type"
    Group="Purchasing Manager Content Types"
    Description=
      "Non-Standard Business Purchase Requests Content Type 
       for the Purchasing Manager Solution"
    Inherits="TRUE"
    Version="0">
    <FieldRefs>
      <FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title"    
        DisplayName="Title" />
      <FieldRef ID="{A74E67E5-8905-4280-90C9-DEBFFC30D43D}" 
        Name="RequestDescription"  
        Required="TRUE" />
      <FieldRef ID="{CB5054F5-0C60-4DBE-94D2-CEFBFB793C7F}" Name="Price" 
        Required="TRUE" />
    </FieldRefs>
  </ContentType>
</Elements>

Después, definiré una lista basada en ese tipo de contenido al hacer clic con el botón secundario sobre PurchasingMgr en el Explorador de soluciones y seleccionaré Agregar nuevo elemento (Add New Item). Seleccionaré la definición de lista de la plantilla de elemento Tipo de contenido, denominaré a la definición de lista NonStandBusPurchaseRequestsListDefn y haré clic en Add (Agregar).

En el Asistente de personalización de SharePoint, seleccionaré el tipo de contenido creado anteriormente y seleccionaré el cuadro "Add a list instance" (Agregar una instancia de lista). El Elements.xml creado para NonStandBusPurchaseRequestsListDefn se muestra en la figura 4.

Figura 4 Definición de NonStandBusPurchaseRequestsListDefn mediante Elements.xml

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="https://schemas.microsoft.com/sharepoint/">
  <!-- Do not change the value of the Name attribute below. 
    If it does not match the folder name of the List Definition project item,
    an error will occur when the project is run. -->
    <ListTemplate
      Name="NonStandBusPurchaseRequestsListDefn"
      Type="10051"
      BaseType="0"
      OnQuickLaunch="TRUE"
      SecurityBits="11"
      Sequence="410"
      DisplayName="Purchasing Manager – 
        Non-Standard Business Purchase Requests List Definition"
      Description=
        "Non-Standard Business Purchase Requests List Definition 
         for the Purchasing Manager Solution"
      Image="/_layouts/images/itgen.png"/>
</Elements>

Observe que cada definición de lista en mi característica se debe identificar mediante un valor Type único mayor a 10.000 (para evitar conflictos con listas definidas por SharePoint) y que uso ese valor para definir cualquier instancia de lista basada en esa definición.

Para agregar las columnas personalizadas a la vista de lista, abriré Schema.xml y agregaré los elementos FieldRef a la vista predeterminada, como se puede apreciar en la figura 5.

Figura 5 Adición de columnas personalizadas a la vista predeterminada de NonStandBusPurchaseRequestsListDefn

<View BaseViewID="1" Type="HTML" WebPartZoneID="Main"  
  DisplayName="$Resources:core,objectiv_schema_mwsidcamlidC24;" 
  DefaultView="TRUE" MobileView="TRUE" MobileDefaultView="TRUE" 
  SetupPath="pages\viewpage.aspx" ImageUrl="/_layouts/images/generic.png" 
  Url="AllItems.aspx">
  <Toolbar Type="Standard" />
  <XslLink Default="TRUE">main.xsl</XslLink>
  <RowLimit Paged="TRUE">30</RowLimit>
  <ViewFields>
    <FieldRef Name="Attachments">
    </FieldRef>
    <FieldRef Name="LinkTitle">
    </FieldRef>
    <FieldRef ID="{A74E67E5-8905-4280-90C9-DEBFFC30D43D}" 
      Name="RequestDescription" />
    <FieldRef ID="{CB5054F5-0C60-4DBE-94D2-CEFBFB793C7F}" Name="Price" />
  </ViewFields>
  <Query>
    <OrderBy>
      <FieldRef Name="ID">
      </FieldRef>
    </OrderBy>
  </Query>
  <ParameterBindings>
    <ParameterBinding Name="NoAnnouncements"   
      Location="Resource(wss,noXinviewofY_LIST)" />
    <ParameterBinding Name="NoAnnouncementsHowTo"   
      Location="Resource(wss,noXinviewofY_DEFAULT)" />
  </ParameterBindings>
</View>

Para terminar, definiré una instancia de la lista al seleccionar ListInstance1 en NonStandBusPurchaseRequestsListDefn y cambiaré su nombre a NonStandBusPurchaseRequestsListInstance. Abriré Elements.xml y agregaré el siguiente código XML para que la lista se base en el tipo de contenido y para que proporcione descripciones prácticas a los usuarios:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="https://schemas.microsoft.com/sharepoint/">
  <ListInstance Title="Non-Standard Business Purchase Requests"
    OnQuickLaunch="TRUE"
    TemplateType="10051"
    Url="Lists/NonStandBusPurchaseRequestsListInstance"
    Description=
      "Non-Standard Business Purchase Requests List 
       for the Purchasing Manager Solution">
  </ListInstance>
</Elements>

En Visual Studio 2010, seleccionaré Debug (Depurar) y después Start Debugging (Iniciar depuración) para probar la solución. La solución está empaquetada e implementada en mi sitio local, como puede apreciarse en la figura 6.

image: Debugging the PurchasingMgr Solution

Figura 6 Depuración de la solución PurchasingMgr

Ahora que probé la solución PurchasingMgr, estoy listo para implementarla en SharePoint Online. Crearé una nueva colección de sitio en SharePoint Online llamada Purchasing (Compras), usando la plantilla Team Site. Volviendo a Visual Studio 2010, empacaré la solución al hacer clic con el botón primario en el proyecto PurchasingMgr en el Explorador de soluciones y al seleccionar Package (Empaque). Para implementar la solución en SharePoint Online, sólo necesito cargarlo a la Galería de soluciones y activar las características de sitio (necesito privilegios de administrador de colección de sitio para hacerlo). Para esto, iniciaré sesión en SharePoint Online y navegaré a mis colecciones de sitio y seleccionaré Site Actions | Site Settings (Acciones de sitio | Configuración de sitio) y después a Solutions (Soluciones) para tener acceso a la Galería de soluciones. Allí, haré clic en la ficha Solutions y seleccionaré Upload Solution (Cargar solución) en la cinta, después iré al archivo PurchasingMgr.wsp en bin\Debug y haré clic en OK (Aceptar) y después en Activate (Activar). Verá la solución en la Galería de solución, como se indica en la Figura 7.

image: PurchasingMgr Solution Deployed to SharePoint Online

Figura 7 Solución PurchasingMgr implementada en SharePoint Online

A continuación, para activar la característica que contiene las columnas de sitio, el tipo de contenido y la lista, navegaré al sitio Purchasing y seleccionaré Site Actions | Site Settings | Manage Site Features (Acciones de sitio | Configuración de sitio | Administrar características de sitio). Seleccionaré la característica Purchasing Manager - Content Types and Lists (Administrador de compras: tipos de contenido y listas) y seleccionaré Activate (Activar). En este momento, deberá poder ver las listas de solicitudes de compra empresarial no estándar en su sitio de SharePoint Online.

El administrador de compras es sólo un ejemplo de lo que se puede lograr en SharePoint Online con las soluciones de recinto de seguridad. Tenga en cuenta las limitaciones en las soluciones de recinto de seguridad y de las características compatibles de SharePoint Online y que puede crear soluciones que se ejecutarán en SharePoint 2010 o SharePoint Online.

Creación de soluciones del lado del cliente con Silverlight

El cliente de OM, el cual también se presentó en SharePoint 2010, proporciona una API orientada a objetos y al lado del cliente para clientes de SharePoint, compilada mediante Microsoft .NET Framework, Silverlight y ECMAScript (lo que incluye JavaScript y JScript) el cual se ejecuta en equipos remotos (lo que incluye el explorador para Silverlight y ECMAScript). La API es coherente con el espacio de nombres del lado del servidor Microsoft.SharePoint, de manera que es fácil de aprender. La API también es coherente con los tipos de clientes compatibles, de manera que es fácil aplicar esa información entre distintas soluciones de cliente. La API del cliente de OM es compatible con SharePoint Online y es una herramienta valiosa para la implementación en la nube.

Por ejemplo, puedo usar el cliente de OM para crear una aplicación de Silverlight 4 para que se agreguen elementos a mi lista y que hospede la aplicación en un elemento web de recinto de seguridad. Para hacer esto, abriré Visual Studio 2010, seleccionaré File | New Project y, en el cuadro de diálogo New Project, seleccionaré Empty SharePoint Project. Nombraré al proyecto PurchasingMgrWP y haré clic en OK. Nuevamente, crearé la solución como una solución en recinto de seguridad y lo indicaré en mi sitio local Purchasing. Para crear la aplicación de Silverlight 4, haré clic con el botón secundario en la solución PurchasingMgrWP, seleccionaré Silverlight en Installed Templates (Plantillas instaladas), seleccionaré Silverlight Application (Aplicación Silverlight) y denominaré a la solución NonStandBusPurchaseReqsSLOM. En el diálogo New Silverlight Application (Nueva aplicación de Silverlight), desactivaré “Host the Silverlight application in a new Web Site” (“Hospedar la aplicación de Silverlight en un nuevo sitio web”), el cual probaremos al hospedar la aplicación en SharePoint, y seleccionaré Silverlight 4 para la versión de Silverlight.

Para hacer referencia a la API del cliente de OM de Silverlight, agregaré referencias a Microsoft.SharePoint.Client.Silverlight.dll y a Microsoft.SharePoint.Client.Silverlight.Runtime.dll en C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\ClientBin. Después, crearé la UI de Silverlight al abrir MainPage.xaml y al reemplazar la XAML con el código en la figura 8.

Figura 8 MainPage.xaml de NonStandBusPurchaseReqsSLOM

<UserControl xmlns:sdk="https://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
  x:Class="NonStandBusPurchaseReqsSLOM.MainPage"
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
  xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
  mc:Ignorable="d"
  d:DesignHeight="300" d:DesignWidth="400">

  <Grid x:Name="LayoutRoot" Background="White">
    <Grid.ColumnDefinitions>
      <ColumnDefinition />
      <ColumnDefinition />
    </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
      </Grid.RowDefinitions>
        
      <sdk:Label Content="Title:" Grid.Column="0" Grid.Row="0" Margin="3"/>
      <sdk:Label Content="Description:" Grid.Column="0" Grid.Row="1" Margin="3"/>
      <sdk:Label Content="Price:" Grid.Column="0" Grid.Row="2" Margin="3"/>
        
      <TextBox Name="Title" Grid.Column="1" Grid.Row="0" Margin="3"/>
      <TextBox Name="Description" Grid.Column="1" Grid.Row="1" Margin="3"/>
      <TextBox Name="Price" Grid.Column="1" Grid.Row="2" Margin="3"/>
        
      <Button Content="Add" Grid.Column="1" Grid.Row="3" Margin="3"     
        Name="addNonStanPurchaseReq" HorizontalAlignment="Right" 
        Height="25" Width="100" Click="addNonStanPurchaseReq_Click" />
  </Grid>
</UserControl>

La XAML en la figura 8 define los cuadros de texto y un botón para recopilar información que se agregará a la lista, como se muestra en la figura 9.

image: MainPage.xaml in Designer

Figura 9 MainPage.xaml en Designer

Haga doble clic en el botón del diseñador y reemplace las clases con el código de la figura 10.

Figura 10 addNonStanPurchaseReq_Click

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using Microsoft.SharePoint.Client;

namespace NonStandBusPurchaseReqsSLOM
{
  public partial class MainPage : UserControl
  {
    private string webUrl;

    public MainPage(string url)
    {
      webUrl = url;

      InitializeComponent();
    }

    private void addNonStanPurchaseReq_Click(object sender, RoutedEventArgs e)
    {   
      ClientContext clientContext = new ClientContext(webUrl);

      Web webSite = clientContext.Web;
      ListCollection webLists = webSite.Lists;

      List nonStandBusPurList = 
        clientContext.Web.Lists.GetByTitle(
        "Non-Standard Business Purchase Requests");

      ListItem newListItem = 
        nonStandBusPurList.AddItem(new ListItemCreationInformation());
        newListItem["Title"] = Title.Text;
        newListItem["RequestDescription"] = Description.Text;
        newListItem["Price"] = Price.Text;
                        
        newListItem.Update();

        clientContext.Load(nonStandBusPurList, list => list.Title);

        clientContext.ExecuteQueryAsync(onQuerySucceeded, onQueryFailed);
    }

    private void onQuerySucceeded(
      object sender, ClientRequestSucceededEventArgs args)
    {
      Dispatcher.BeginInvoke(() =>
      {
        MessageBox.Show("New item added.");
      });
    }


    private void onQueryFailed(object sender, 
      ClientRequestFailedEventArgs args)
    {
      Dispatcher.BeginInvoke(() =>
      {
        MessageBox.Show("Request failed. " + args.Message + "\n" + 
          args.StackTrace);
      });
    }
  }
}

El código en la figura 10 tiene un modelo en común en el código del cliente de OM. Primero, obtendré acceso al contexto del cliente mediante la clase ClientContext (el cual equivale a la clase SPContext). A continuación, haré acceso al sitio y a la lista mediante las clases Web, ListCollection y List, respectivamente. Observe las similitudes de las clases SPWeb, SPListCollection y SPList. Por último, crearé un ListItem al llamar al método List.AddItem, lo rellenaré con datos de la UI y llamaré al método ListItem.Update. ListItem no se crea hasta que se llame a los métodos ClientContext.Load y ClientContext.ExecuteQueryAsync para que ejecuten la consulta. Observe que puede evitar viajes al servidor al cargar consultas múltiples mediante ClientContext.Load, al llamar al método ClientContext.ExecuteQueryAsync.

Para implementar la aplicación Silverlight 4, agregaré un módulo para implementar la aplicación con el proyecto de elemento de web. Seleccionaré PurchasingMgrWP en el Explorador de soluciones, haga clic con el botón secundario y seleccione Add | New Item | Module (Agregar | Nuevo elemento | Módulo) y denomine al módulo ClientBin. Reemplazaré los contenidos de Elements.xml creados con este código XML:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="https://schemas.microsoft.com/sharepoint/">
  <Module Name="ClientBin">
    <File Path="ClientBin\NonStandBusPurchaseReqsSLOM.xap"  
      Url="ClientBin/NonStandBusPurchaseReqsSLOM.xap" />
  </Module>
</Elements>

Este código XML implementa el archivo NonStandBusPurchaseReqsSLOM.xap en la carpeta ClientBin en el sitio de SharePoint.

Para implementar la salida del proyecto NonStandBusPurchaseReqsSLOM con el módulo ClientBin, seleccionaré el módulo ClientBin en el Explorador de soluciones y abriré el cuadro de diálogo de propiedad Project Output References (Referencias de salida de proyecto). Haré clic en Add y seleccionaré NonStandBusPurchaseReqsSLOM como el nombre de proyecto y ElementFile como DeploymentType.

A continuación, agregaré un elemento web personalizado a mi solución de SharePoint para hospedar la aplicación de Silverlight. Seleccionaré PurchasingMgrWP en el Explorador de soluciones, haga clic con el botón secundario y seleccione Add | New Item, seleccione Web Part (elemento web) y denomine al elemento web NonStandBusPurchaseReqsWP. Usaré un elemento web personalizado para entregarle parámetros a la aplicación de Silverlight, como la URL del sitio usado para crear ClientContext. Para permitir esto, agregaré una clase auxiliar llamada SilverlightObjectTagControl.cs y reemplazaré el cuerpo de esa clase con el código en la figura 11.

Figura 11 Agregado de la clase auxiliar SilverlightObjectTagControl.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace PurchasingMgrWP
{
  class SilverlightObjectTagControl : WebControl
  {
    public string Source { get; set; }
    public string InitParameters { get; set; }

    protected override void CreateChildControls()
    {
      base.CreateChildControls();

      if (Source != null && Source != "")
      {
        string width = (this.Width == Unit.Empty) ? "400" : 
          this.Width.ToString();
        string height = (this.Height == Unit.Empty) ? "300" : 
          this.Height.ToString();

        this.Controls.Add(new LiteralControl(
          "  <div>" +
          "  <object data=\"data:application/x-silverlight-2,\" +
          "  type=\"application/x-silverlight-2\" width=\"" + width +         
          "  "\" height=\"" + height + "\">" +
          "  <param name=\"source\" value=\"" + Source + "\"/>" +
          "  <param name=\"onerror\" value=\"onSilverlightError\" />" +
          "  <param name=\"background\" value=\"white\" />" +
          "  <param name=\"minRuntimeVersion\" value=\"4.0.50826.0\" />" +
          "  <param name=\"autoUpgrade\" value=\"true\" />" +
          "  <param name=\"initparams\" value=\"" + InitParameters + "\" />" +
          "  <a href=\"https://go.microsoft.com/fwlink/?LinkID=" +
          "  149156&v=4.0.50826.0\" +
          "  style=\"text-decoration: none;\">" +
          "  <img src=\"https://go.microsoft.com/fwlink/?LinkId=161376\" +
          "  alt=\"Get Microsoft Silverlight\" style=\"border-style: none\"/>" +
          "  </a>" +
          "  </object>" +
          "  <iframe id=\"_sl_historyFrame\" +
          "  style=.visibility:hidden;height:0;width:0;border:0px.></iframe>" +
          "  </div>"
          ));

      }
    }
  }
}

La clase SilverlightObjectTagControl.cs en la figura 11 tiene dos propiedades: Source pasa la URL de la aplicación Silverlight para que se cargue en el elemento web e InitParameters pasa los parámetros de inicialización a la aplicación de Silverlight 4. Estas propiedades se usan para compilar la etiqueta <object /> de la aplicación Silverlight en el método CreateChildControls. Para usar esta clase, abra NonStandBusPurchaseReqsWP.cs y reemplace el código en esa clase con el código en la figura 12.

Figura 12 NonStandBusPurchaseReqsWP.cs

using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;

namespace PurchasingMgrWP.NonStandBusPurchaseReqsWP
{
  [ToolboxItemAttribute(false)]
  public class NonStandBusPurchaseReqsWP : WebPart
  {
    protected override void CreateChildControls()
    {
      base.CreateChildControls();

      SilverlightObjectTagControl slhc = 
        new SilverlightObjectTagControl();
      slhc.Source = SPContext.Current.Site.Url + 
        "/ClientBin/NonStandBusPurchaseReqsSLOM.xap";
      slhc.InitParameters = "url=" + SPContext.Current.Web.Url;

        this.Controls.Add(slhc);
    }
  }
}

El código de la figura 12 crea una instancia de SilverlightObjectTagControl, configura la propiedad Source de la URL de la aplicación Silverlight en ClientBin y configura la propiedad InitParameters para que conserve la URL del sitio actual (donde está la lista de solicitudes de compra empresarial no estándar). Para pasar la URL al constructor de la clase MainPage en NonStandBusPurchaseReqsSLOM, abra App.xaml.cs y agregue el siguiente código en el evento Application_Startup:

private void Application_Startup(object sender, 
    StartupEventArgs e)
  {
    string url = e.InitParams["url"];

    this.RootVisual = new MainPage(url);
  }

Para probar el elemento web, implemente el paquete PurchasingMgr.wsp en el sitio Purchasing local para implementar la lista de solicitudes de compra empresarial no estándar (se eliminó la lista cuando la sesión de depuración listada anterior finalizó) y después depurar la solución PurchasingMgrWP desde Visual Studio 2010. Al agregarlo a \Purchasing\Home.aspx, el elemento web permite agregar elementos directamente a la lista desde Silverlight, como se puede ver en la figura 13 y la figura 14.

image: The NonStandBusPurchaseReqsWP in Action

Figura 13 NonStandBusPurchaseReqsWP en acción

image: The Updated Non-Standard Business Purchase Requests List

Figura 14 La lista de solicitudes de compra empresarial no estándar actualizada

Desarrollar y depurar el sitio frente al sitio local me permite usar Visual Studio 2010 para depurar tanto el código de SharePoint y como el de Silverlight 4 hasta que se haya probado por completo la solución. Llegado a este momento, cargaré PurchasingMgrWP.wsp a la Galería de soluciones en SharePoint Online.

El cliente de OM de SharePoint proporciona una API familiar, persistente y orientada a objetos para tener acceso a listas y bibliotecas en SharePoint Online. La API es un subconjunto de la API de Microsoft.SharePoint y se orientan hacia la colección de sitio y elementos jerárquicos menores, lo cual está alineado perfectamente al desarrollo de SharePoint Online.

Soluciones de SharePoint en la nube

En síntesis, SharePoint Online proporciona a los desarrolladores de SharePoint una oportunidad única para compilar soluciones para la nube usando las competencias y herramientas que ya tienen. Al comprender las características de personalización de SharePoint Online (lo que incluye lo que es y lo que no es compatible), las soluciones de recinto de seguridad, el cliente de OM de SharePoint los flujos de trabajo declarativos compilados usando SharePoint Designer 2010, puede compilar soluciones de SharePoint que se ejecutan en la nube con SharePoint Online. Para actualizado acerca del desarrollo de SharePoint Online a través del proceso del beta, revise el centro de recursos de desarrollador de SharePoint Online (msdn.com/sharepointonline).

Chris Mayo es un especialista en tecnología enfocado en Office 365 y SharePoint Online. Él tiene experiencia tanto como escritor como orador en la comunicación de contenidos técnicos a audiencias que varían en tamaño, desde grupos pequeños a miles de personas. Es coautor de “Programming for Unified Communications with Microsoft Office Communications Server 2007 R2” (Microsoft Press, 2009). Hace 10 años que trabaja con Microsoft. Antes de unirse a Microsoft, trabajó como desarrollador y arquitecto en departamentos de TI de compañías de las industrias de finanzas y venta minorista que forman parte de la lista Fortune 500. Esté al tanto de las últimas actividades de Mayo en su blog, blogs.msdn.com/b/cmayo.

Gracias a los siguientes expertos técnicos por su ayuda en la revisión de este artículo: George Durzi, Steve Fox, AJ May y Christina Storm