This Blog

Syndication

Search

Tags

Community

Email Notifications

Archives

Enlaces Recomendados

October 2011 - Artículos

SharePoint 2010: ¿Para qué sirve la propiedad AllowUnsafeUpdates?

Si algo caracteriza a SharePoint es que está diseñado con la idea de que sea seguro y se eviten por ejemplo situaciones de cross-site scripting cuando estamos creando artefactos en los que se hace uso del modelo de objetos (MO)…y de aquí viene la idea de escribir este artículo. Básicamente SharePoint aplica una comprobación de seguridad cada vez que se realiza un cambio de información o datos a través del MO en peticiones HTTP. De hecho, los propios formularios de SharePoint utilizan un “form digest control” para forzar y garantizar que las operaciones sean seguras. Esto implica que cuando se realizan cambios en datos de SharePoint a través del MO en un GET, SharePoint “escupirá” una excepción de validación de seguridad…algo así como “Microsoft.SharePoint.SPException: The Security validation for this page is invalid”…la pregunta que surge aquí es si esta validación la podemos “saltar” en formularios o páginas que no herden de la propia infraestructura de páginas de SharePoint…la respuesta es que sí a través de la propiedad AllowUnsafeUpdates presente en SPSite y SPWeb:

   1: SPWeb spwWeb = SPContext.Current.Web:
   2: SPList splLista = spwWeb.Lists["Mi Lista"];
   3: try{
   4:     spwWeb.AllowUnsafeUpdates=true;
   5:     splLista.Title="Nuevo Título";
   6:     splLista.Update();
   7: }
   8: finally{
   9:     spwWeb.AllowUnsafeUpdates=false;
  10: }

Referencias:

Publicado 31/10/2011 16:23 por Juan Carlos González Martín | 1 comment(s)

SharePoint 2010: Como tener BD’s de contenido diferentes por colección de sitios (I)!

Como ocurría en SharePoint 2007, en SharePoint 2010 a la hora de crear nuevas colecciones de sitios tenemos la posibilidad de hacerlo sobre bases de datos (BDs) de contenidos independientes en lugar de hacerlo sobre la BD creada inicialmente cuando se creo la aplicación web bajo la que se están definiendo las colecciones de sitios. El proceso a seguir para esta configuración es el siguiente:

  • En la Administración Central de SharePoint 2010 nos vamos a la sección Bases de Datos dentro Administración de Aplicaciones. Aquí pulsamos sobre el enlace “Administrar bases de datos de contenidos”.
  • En la página que se abre, podemos ver el listado de BDs de contenidos disponibles para cada aplicación web que seleccionemos. En el caso de ejemplo, tenemos una única BD de contenidos que procedemos a editar a través del correspondiente enlace.
  • En la página de configuración de la BD cambiamos el estado de la misma a “Sin conexión” de manera que se puede seguir trabajando con las colecciones de sitios ya creadas en dicha BD, pero no se pueden crear nuevas colecciones sobre la misma.
image image image
  • De vuelta al listado de BD’s de contenido veremos que el estado de la BD aparece como “Detenido”. Si pulsamos sobre “Agregar nueva base de datos de contenido” procederemos a crear una nueva BD de contenidos para la aplicación web.
  • En este caso, los parámetros mínimos para su creación son el nombre del servidor de BD y el nombre de la BD de contenidos a crear.
  • Una vez que hemos creado la BD, veremos que el estado de la misma en el listado de BDs de contenidos vinculadas a la aplicación web es “Iniciado” de manera que cada nueva colección de sitios que se cree en la aplicación web residirá en esta BD.
image image image

Publicado 30/10/2011 12:27 por Juan Carlos González Martín | 1 comment(s)

Productividad: Nuevo video de Microsoft sobre la visión particular de Microsoft!

Cada cierto tiempo Microsoft publica videos en torno a su visión particular de la tecnología en los próximos años y anticipando como será la forma que tendremos de interactuar con la misma, siempre con un cierto toque futurista claro está. El último video enfocado a temas de productividad lo podéis localizar desde este enlace y os lo dejo en este post…merece la pena.

Productivity Future Vision (2011)

Publicado 29/10/2011 13:26 por Juan Carlos González Martín | con no comments

Archivado en:

SharePoint 2010: Como usar un entorno compartido de CloudShare durante 14 días!

Como ya he comentado en varios posts, en mi caso tengo mi entorno de pruebas y desarrollo de SharePoint 2010 montado en CloudShare lo que me facilita el disponer del HW adecuado para poder aprovechar toda las capacidades de la plataforma sin problemas de rendimiento, realizar snapshots del entorno de manera que pueda volver a una versión estable en cualquier momento o compartir este entorno a través de la siguiente Url: http://use.cloudshare.com/Pro/ShareEnv/QAU2K5Q5K4KH. De manera que cualquiera puede durante 14 días usar dicho entorno…y precisamente sobre estos 14 días va el post de hoy ya que el tiempo de vida inicial del entorno una vez que se usa la Url anterior y se crea la cuenta de CloudShare es de 2 días, por lo que para poder usarlo durante 14 días en modo trial tenemos que hacer lo siguiente:

  • En primer lugar, tras introducir la Url anterior en nuestro navegador habitual tendremos que rellenar un formulario para crear una cuenta de CloudShare.
  • Una vez introducidos los datos y tras realizar el envío de los mismos, recibiremos en el correo electrónico un código de activación que tenemos que usar en la siguiente página que se muestra en el proceso de dar de alta la cuenta.
  • Tras pulsar “Verify” seremos redirigidos al entorno compartido que está basado en el último snapshot realizado por el usuario de CloudShare y que ha compartido con el enlace anterior (denominado Permalink en la plataforma CloudShare). Este entorno lo podremos usar durante 2 días, y para poder extender su uso a los 14 días que tenemos para probar CloudShare con la cuenta Trial que acabamos de crear pulsamos en primer lugar el botón “View environment”.
image image image
  • A continuación, accedemos al entorno de CloudShare y esperamos a que las máquinas que lo constituyen se hayan iniciado. En ese momento, se habilitará el botón “Take ownership” que nos permite hacernos propietarios de ese entorno compartido durante el tiempo de vida de la cuenta Trial, es decir, los 14 días comentados.
  • Tras pulsar ese botón, podremos comprobar que efectivamente el tiempo de vida del entorno ha pasado de los 2 días iniciales a loas 14 comentados.
image image

Para concluir el post, quería comentaros que esta funcionalidad de crear y compartir entornos con buenas prestaciones en términos de HW, además de otras muchas capacidades, la tenéis disponible dentro del servicio CloudShare Pro Plus y si estás interesados en adquirir el servicio puedo conseguiros descuentos. Finalmente, os recuerdo otros posts sobre el uso de CloudShare con SharePoint:

Publicado 29/10/2011 10:08 por Juan Carlos González Martín | 1 comment(s)

SharePoint 2010: Cómo crear un nivel de permisos a partir de uno existente (I)!

Como sabéis, todo sitio de SharePoint 2010 dispone por defecto de unos niveles de permisos que son función de la plantilla de sitio en la que se basa el sitio y que definen una agrupación de permisos individuales. Por supuesto, es posible crear nuevos niveles de permisos desde cero o bien a partir de uno existente:

  • Entramos en la página de configuración del sitio y bajo la sección Usuarios y permisos pulsamos sobre Permisos el sitio.
  • En la página con el listado de grupos de SharePoint del sitio y el nivel de permisos asociado, pulsamos sobre la opción “Niveles de permisos” de la Ribbon.
  • En la nueva página que se abre podremos crear un nuevo nivel de permisos desde cero o bien visualizar el detalle de un nivel existente para poder crear un nuevo nivel basado en el mismo.
image image image
  • Entramos en la página de detalle de uno de los niveles de permisos existentes.
  • Pulsamos el botón “Copiar nivel de permisos”.
  • A continuación se muestra una nueva página en la que podremos especificar el nombre del nuevo nivel de permisos y añadir nuevos permisos individuales si es necesario.
image image image

Publicado 28/10/2011 21:38 por Juan Carlos González Martín | 1 comment(s)

SharePoint Online: Las actualizaciones prometidas ya están aquí :-)!

Como comenté en este artículo y se reveló en la SharePoint Conference de este año, la primera actualización para SharePoint Online estaba al caer…y ya ha caído. Esta mañana, después del correspondiente aviso por correo electrónico, pude comprobar como en la administración de SharePoint Online aparecen dos nuevos enlaces relativos a la conectividad de datos empresariales (o BCS) y el servicio de almacenamiento seguro (SSS):

  • Al acceder a la Tenant Administration de SharePoint Online, aparecen los dos nuevos enlaces comentados.
  • El primero de los enlaces permite acceder a la administración de los tipos de contenido externo que tengamos disponibles y realizar algunas de las configuraciones que conocemos de SharePoint On-Premise como dar permisos en los tipos de contenido externo disponibles, asignar administradores al almacén de metadatos, etc.
  • En el caso del servicio de almacenamiento seguro podremos crear IDs de aplicación que luego podamos usar para conectarnos a sistemas externos (os recuerdo que tiene que ser a través de servicios WCF).
image image image

Si navegamos a una de las colecciones de sitios disponibles, podremos ver que si eliminamos un sitio tenemos operativa y disponible la papelera de reciclaje de sitios:

image

Publicado 27/10/2011 15:07 por Juan Carlos González Martín | 5 comment(s)

SharePoint 2010: Desarrollo y depuración contra sitios remotos (I)!

Una pregunta habitual cuando se comienza a desarrollar en plataforma SharePoint es la relativa a como tiene que ser el entorno de desarrollo de manera que surgen interrogantes como: ¿Necesito tener instalado SharePoint 2010 en mi máquina de desarrollo? ¿Puedo evitar tener que instalarlo y sólo disponer de Visual Studio 2010? ¿Tiene sentido que todos los desarrolladores trabajen contra una misma instalación de SharePoint?, … seguro que a más de uno os han llegado este tipo de inquietudes. Lo primero que tenemos que tener en cuenta para ir respondiendo a las mismas es:

  • Los requerimientos de base para desarrollar contra SharePoint oficialmente publicados por Microsoft y expertos en la materia:
  • Aunque la recomendación es que cada desarrollador disponga de un entorno desarrollo completo de acuerdo a los requerimientos anteriores y teniendo en cuenta la flexibilidad de que disponemos para su configuración como ya comente en esta serie de posts, puede ser que en ciertos escenarios haya que buscar alternativas o workarounds no soportados y totalmente improductivos en el desarrollo en SharePoint que implique desarrollar en local sin tener instalado SharePoint 2010 y depurar de forma remota contra un servidor en el que si tengamos instalado SharePoint. Para que esto sea posible, y en función del tipo de solución (Sandbox vs Granja) tendremos que realizar una serie de configuraciones manuales en el servidor remoto de SharePoint como se indica en las siguientes referencias:
  • ¿Qué inconvenientes le veo yo a esta aproximación de desarrollo? Pues varios:
    • El primero, que tenemos que copiar el depurador de nuestro entorno de desarrollo al servidor…si se trata de un servidor de “desarrollo” esto no es tan malo, pero si es directamente el servidor de “pre-producción” ya estamos violando una de las reglas de que el ambiente de “pre-producción” debería ser una réplica al de producción…al meter estos ente extraño, estamos añadiendo una primera diferencia.
    • En segundo lugar, la creación y configuración de cuentas de depuración en el servidor que necesitemos para que la depuración remota sea posible.
    • En tercer lugar, el tiempo que tendremos que invertir (estas configuraciones no son inmediatas) para que la depuración remota esté operativa. Tiempo tanto de nuestros desarrolladores como de nuestro personal de IT.
    • Finalmente, y aunque la depuración remota es posible, en ningún sitio veréis que Microsoft recomiende su configuración y uso por sistema para crear soluciones para SharePoint…se debería utilizar la depuración remota cuando nos encontremos ante expedientes X en nuestros desarrollos que nos obliguen a depurar que está pasando en el servidor.

Finalmente os dejo una serie de referencias adicionales en torno a estas configuraciones que complementan a las ya comentadas:

Publicado 26/10/2011 23:23 por Juan Carlos González Martín | 2 comment(s)

WSS 3.0 & MOSS: Disponible el SP3!

Tal y como podéis leer en este enlace, Microsoft acaba de liberar el service pack 3 (SP3) para la versión 2007 de SharePoint (WSS 3.0 & MOSS). En ese mismo post se comenta que junto con el SP3 de SharePoint, también tenemos disponible el SP3 de Office 2007. Los enlaces de descarga respectivos son los siguientes:

2007 Microsoft Office Suite Service Pack 3 (SP3) and Microsoft Office Language Pack 2007 SP3

2526086

Suite: 32-bit ; LPK: 32-bit

2007 Microsoft Office servers Service Pack 3 (SP3) and 2007 Microsoft Office servers Language Pack (SP3)

2526299

Server Suite: 32-bit; LPK: 32-bit ; Server Suite: 64-bit; LPK: 64-bit

Office SharePoint Designer 2007 Service Pack 3 (SP3) and of Office SharePoint Designer Language Pack 2007 SP3

2526089

SharePoint Designer: 32-bit; LPK: 32bit

Office Project 2007 Service Pack 3 (SP3) and of Office Project Language Pack 2007 SP3

2526091

Project: 32-bit; Project LPK: 32-bit

Office Visio 2007 Service Pack 3 (SP3) and of Office Visio Language Pack 2007 SP3

2526291

Visio: 32-bit; Visio LPK: 32-bit

Office Proofing Tools 2007 Service Pack 3 (SP3)

2526293

32-bit

Microsoft Office Language Interface Pack 2007 Service Pack 3 (SP3)

2526307

32-bit

PowerPoint Viewer 2007 Service Pack 3 (SP3)

2526298

32-bit

Visio Viewer 2007 Service Pack 3 (SP3)

2526301

32-bit

Excel Viewer 2007 Service Pack 3 (SP3)

2526302

32-bit

Calendar Printing Assistant for Outlook 2007 Service Pack 3 (SP3)

2526294

32-bit

Microsoft Office InterConnect 2007 Service Pack 3 (SP3)

2526296

32-bit

Office Compatibility Pack Service Pack 3 (SP3)

2526297

32-bit

Microsoft Office Access Runtime and Data Connectivity Components 2007 Service Pack 3 (SP3)

2526310

32-bit

Windows SharePoint Services 3.0 Service Pack 3 (SP3) and of Windows SharePoint Services 3.0 Language Pack SP3

2526305

WSS 3.0: 32-bit; LPK: 32-bit ; WSS 3.0: 64-bit; LPK: 64-bit

Microsoft Expression Web 3 Service Pack 3 (SP3) and of Microsoft Expression Web Language Pack SP3

2575737

Expression Web : 32-bit; LPK: 32-bit

Known issues that you may experience when you install the 2007 Microsoft Office suite Service Pack 3 (SP3) and Windows SharePoint Services 3.0 SP3

2591067

n/a

List of all 2007 Office system Service Pack 3 and Windows SharePoint Services 3.0 Service Pack 3 packages

2591018

n/a

Technical details about the 2007 Microsoft Office System Service Pack 3 (SP3) releases

2591039

n/a

Technical details about the 2007 Microsoft Office Servers Service Pack 3 (SP3) releases

2591050

n/a

Technical details about the Windows SharePoint Services 3.0 Service Pack 3 (SP3) releases

2591054

n/a

Publicado 26/10/2011 9:08 por Juan Carlos González Martín | con no comments

Archivado en: ,

SharePoint 2010: Como ejecutar un flujo de trabajo en varios elementos a la vez!

Una necesidad con la que me he encontrado hace poco es la de poder ejecutar un flujo de trabajo sobre varios elementos de una lista de forma simultanea. Por defecto, esta acción no se considera como “multi-elemento” en SharePoint 2010 por lo que necesariamente tenemos que buscar un workaround para conseguirlo…además, en mi caso resulta que no tengo posibilidad de desplegar lógica en el servidor por lo que necesariamente se tuvo que pensar en una solución con “cero” desarrollo…como habréis adivinado, esto nos lleva a pensar que posibilidades nos puede brindar SharePoint Designer 2010 (SPD 2010) para conseguir esto. Y efectivamente, es en el entorno de SPD 2010 junto con las posibilidades de la DataFormWebPart dónde podremos dar respuesta a esta necesidad…cómo siempre, alguien ya encontró el workaround que podéis encontrar en este enlace…solución efectiva diría yo.

SharePoint2010_thumb

Publicado 25/10/2011 20:55 por Juan Carlos González Martín | 1 comment(s)

SharePoint 2010: Apertura de ventanas modales y páginas desde acciones personalizadas (III)!

Siguiendo con la serie de posts en torno a la apertura de ventanas modales y páginas desde acciones personalizadas, en este nuevo artículo vamos a ver como podemos crear una acción personalizada de forma programática (que no declarativa) vinculada a una lista en exclusiva (algo que declarativamente no es posible de forma sencilla) y además desplegarla en nuestro sitio de SharePoint como una solución Sandbox lo que nos permitiría su uso en SharePoint Online en Office 365. Pero antes, os recuerdo los dos artículos previos de la serie:

Para abrir una ventana modal mediante una acción personalizada creada de forma programática:

  • En Visual Studio creamos un proyecto de tipo “Empty SharePoint Project”.
  • En el asistente de configuración especificamos como tipo de despliegue Sandbox.
  • Una vez creado el proyecto, a través del explorador de soluciones y situándonos en el nodo Feature añadimos una característica.
image image image
  • Configuramos la característica de forma adecuada, y le añadimos un Feature Event Receiver que es dónde vamos a añadir toda la lógica para la creación de la acción personalizada de forma programática.
  • Configuramos el método FeatureActivated() de la siguiente forma:
       1: public override void FeatureActivated(SPFeatureReceiverProperties properties)
       2: {
       3:     SPWeb spwWeb = (SPWeb)properties.Feature.Parent;        
       4:     SPList splList = spwWeb.Lists.TryGetList("Tareas");
       5:     SPUserCustomAction spucCustomAction = splList.UserCustomActions.Add();
       6:     spucCustomAction.Location = "CommandUI.Ribbon.ListView";
       7:     spucCustomAction.Sequence = 85;
       8:     spucCustomAction.Title = "Ayuda";
       9:     spucCustomAction.CommandUIExtension =
      10:         @"<CommandUIExtension>"Ribbon.ListItem.Actions.Controls._children"">"Ribbon.ListItem.Actions.Controls.HelpButton"" TemplateAlias=""o1"" Command=""HelpCommand"" "http://demo2010a:100/sites/PortalIntranet/Documentos%20compartidos/Logo_Ayuda.gif"" "General"" LabelText=""Ayuda"" />"HelpCommand"" CommandAction=""BLOCKED SCRIPTSP.UI.ModalDialog.showModalDialog({url:'/_layouts/help.aspx',dialogReturnValueCallback: function(dialogResult, returnValue) { SP.UI.ModalDialog.RefreshPage(SP.UI.DialogResult.OK) }})""/>;
      11:             <CommandUIDefinitions>
      12:                 <CommandUIDefinition Location="
      13:                     <Button Id="
      14:                     Image32by32="
      15:                     CommandType="
      16:                 </CommandUIDefinition>
      17:             </CommandUIDefinitions>
      18:             <CommandUIHandlers>
      19:                 <CommandUIHandler Command ="
      20:             </CommandUIHandlers></CommandUIExtension>"
      21:     spucCustomAction.Update();
      22: }
  • Como vemos, la gracia de pode añadir una acción personalizada a una lista en concreta radica en crear una instancia de SPUserCustomAction que nos habilita para:
    • Añadir una acción personalizada a la lista deseada.
    • Especificar la ubicación de la acción a través de la propiedad Location.
    • Especificar el orden de aparición de la acción mediante la propiedad Sequence.
    • Y finalmente, y lo más importante, especificar la definición completa de la acción a través de la propiedad CommandUIExtension. Fijaros que aquí se está indicando la ubicación concreta de la acción (en la Ribbon de lista, en la sección Acciones), la imagen a utilizar (previamente cargada en el sitio o provisionada en el propio proyecto mediante un elemento de tipo módulo), y el comando que en este caso nos permite levantar la ventana modal especificando un bloque JavaScript que hace uso del Framework de ventanas modales.
  • Configuramos el método FeatureDeactivating() para realizar la correspondiente limpieza:
   1: public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
   2: {
   3:     SPWeb spwWeb = (SPWeb)properties.Feature.Parent;                
   4:     SPList splList = spwWeb.Lists.TryGetList("Tareas");
   5:     SPUserCustomActionCollection spuccCustomActionsConllection =
   6:         splList.UserCustomActions;
   7:     foreach (SPUserCustomAction spucCustomAction in spuccCustomActionsConllection)
   8:     {
   9:         if (spucCustomAction.Title == "Ayuda")
  10:         {
  11:             spucCustomAction.Delete();
  12:             break;
  13:         }
  14:     }
  15: }
  • Compilamos el proyecto y lo desplegamos en nuestro sitio de SharePoint. Comprobamos que la acción personalizada se ha añadido correcatamente en la Ribbon.
  • Finalmente comprobamos que la acción funciona como se espera:
image image

Referencias:

Publicado 24/10/2011 16:19 por Juan Carlos González Martín | 2 comment(s)

SharePoint 2010: Tokens que podemos usar en redirecciones!

A menudo cuando estamos añadiendo funcionalidad adicional en una solución SharePoint nos podemos encontrar con la necesidad de hacer redirecciones a ciertas páginas. Por ejemplo, desde una nueva opción de menú de elemento de lista navegar a una página concreta o a un formulario de edición de elemento que hayamos creado de forma personalizada. Pues bien, a la hora de especificar Urls de redirección a páginas de SharePoint disponemos de una serie de tokens que nos facilitan que las mismas sean + o – dinámicas. Estos tokens son:

  • ~sitecollection, para marcar que nos estamos refiriendo a una colección de sitios (SPSite).
  • ~site, para marcar que nos estamos refiriendo a un sitio de SharePoint (SPWeb).
  • {SiteUrl}, que nos proporciona la Url del sitio (de nuevo SPWeb).
  • {ListId}, que nos da acceso al ID de la lista sobre la que estamos definiendo la acción.
  • {ItemId}, para marcar que nos estamos refiriendo al ID del elemento seleccionado.
  • {ItemUrl}, que indica la Url del elemento actual.
  • {RecurrenceId}.

Por ejemplo, para especificar una redirección en una acción personaliza usando estos parámetros mediante un elemento de tipo <UrlAction> tendríamos:

   1: <UrlAction Url="~site/_layouts/CustomApplicationPage/CustomApplicationPage.aspx?ItemId={ItemId}&amp;ListId={listId}/>
De esta forma estaríamos haciendo una redirección a la página de aplicación CustomApplicationPage.aspx y pasando por parámetro el Id del elemento actual y el Id de la lista a la que pertenece.

Publicado 23/10/2011 20:06 por Juan Carlos González Martín | 1 comment(s)

SharePoint 2010: Controles delegados (I)!

Los controles de tipo delegado están pensados para cambiar el look & feel de un sitio de SharePoint ya que actúan como contenedores que encapsulan contenido por defecto (un conjunto de controles hijos). Lo interesante de estos controles, que SharePoint utiliza de una forma “intensiva” es que tenemos la posibilidad de “machacar” el contenido por defecto y añadir controles específicos a partir de desplegar la correspondiente feature. Algunos ejemplos de controles delegados disponibles a nivel de página maestra son: To Navigation Data Source, Left Navigation Data Source, Search Box, etc. Si editamos la página maestra de un sitio de SharePoint convencional (la v4.master de un sitio de tipo sitio de grupo) veremos que hay numerosas instancias de tipo <SharePoint: DelegateControl />. Este es un control que define un contenedor con un atributo ControlId único en la página o en la página maestra y que será reemplazado durante el renderizado de la misma por el control de servidor adecuado:

   1: <SharePoint:DelegateControl runat="server" ControlId="AdditionalPageHead" 
   2: AllowMultipleControls="true"/>
   3: <SharePoint:DelegateControl runat="server" ControlId="GlobalNavigation" />
   4: <SharePoint:DelegateControl runat="server" ID="GlobalDelegate0" ControlId="GlobalSiteLink0" />
   5: <SharePoint:DelegateControl ControlId="GlobalSiteLink2" ID="GlobalDelegate2" Scope="Farm"
   6:  runat="server" />
   7: <SharePoint:DelegateControl runat="server" ControlId="PublishingConsole" 
   8: Id="PublishingConsoleDelegate">
   9: </SharePoint:DelegateControl><SharePoint:DelegateControl ControlId="GlobalSiteLink3" Scope="Farm" 
  10: runat="server" />
  11: <SharePoint:DelegateControl runat="server" ControlId="SmallSearchInputBox" Version="4" />
  12: <SharePoint:DelegateControl runat="server" ControlId="TopNavigationDataSource" 
  13: Id="topNavigationDelegate"/>

Si editamos la página maestra v4.master con SharePoint Designer 2010 (SPD 2010) podremos ver estas instancias. Por ejemplo, podemos localizar fácilmente la relativa al control de búsqueda típico de SharePoint:

   1: <SharePoint:DelegateControl runat="server" ControlId="SmallSearchInputBox" Version="4"/>

Para sobreescribir el comportamiento de un control delegado por defecto en tiempo de ejecución (por ejemplo el de búsqueda):

  • Por defecto este control delegado es reemplazado por el control nativo propio de SharePoint que en el caso de la versión server se encuentra definido en la clase Microsoft.SharePoint.Portal.WebControls.SearchBoxEx.
  • En Visual Studio 2010 creamos un proyecto de SharePoint 2010 de tipo vacío y elegimos como tipo de despliegue “Deploy as farm solution”.
  • Añadimos al proyecto un elemento de tipo vacío, de forma que se crea la correspondiente feature que configuramos de forma adecuada (título, descripción, propiedades, etc).
  • Configuramos el archivo Elements.xml de la siguiente forma:
   1: <?xml version="1.0" encoding="utf-8"?>
   2: <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
   3:     <Control Id="SmallSearchInputBox"
   4:              Sequence="10"
   5:              ControlAssembly="$SharePoint.Project.AssemblyFullName$"
   6:              ControlClass="SPDelegateSearchControl.CustomSearchControl" />
   7:     <Control Id="SmallSearchInputBox"
   8:              Sequence="5"
   9:                ControlClass="Microsoft.SharePoint.Portal.WebControls.SearchBoxEx"
  10:                ControlAssembly="Microsoft.Office.Server.Search, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">
  11:         <Property Name="FrameType">None</Property>
  12:         <Property Name="DropDownMode">ShowDD</Property>
  13:         <Property Name="TextBoxWidth">200</Property>
  14:         <Property Name="ShowAdvancedSearch">true</Property>
  15:         <Property Name="QueryPromptString">Your search here...</Property>
  16:         <Property Name="SearchBoxTableClass">search-box</Property>
  17:     </Control>
  18: </Elements>
  • Como vemos, estamos añadiendo dos posibles controles delegados relativos a la caja de búsqueda de SharePoint (SmallSearchInputBox):
    • El primero de ellos haría referencia a una implementación propia del control de búsqueda.
    • El segundo, lo que hace es añadir configuraciones adicionales al control de búsqueda existente por defecto en la plataforma.
    • El atributo Sequence le va a indicar a SharePoint que control usar, teniendo en cuenta que considerará aquel control que tenga un valor mñas bajo para dicho atributo.

Hacemos el despliegue del proyecto y comprobamos que la personalización del control delegado se ha aplicado

image image image

 

Algunas referencias sobre controles delegados:

Publicado 22/10/2011 12:31 por Juan Carlos González Martín | 2 comment(s)

SharePoint 2010: Manejadores de eventos síncronos vs asíncronos (I)!

Como sabéis, desde SharePoint 2007 contamos con la posibilidad de añadir cierta lógica a nuestras soluciones de SharePoint mediante los denominados manejadores de eventos que no dejan de ser clases que heredan de clases base especificas a ciertos eventos de SharePoint: SPItemEventReceiver para eventos relativos a elementos de lista / biblioteca de documentos, SPListEventReceiver para eventos relativos a listas, SPFeatureReceiver para eventos relativos a características, etc. Todas estas clases, salvo en el caso de SPEmailEventReceiver y SPFeatureReceiver, heredan de una misma clase base SPEventReceiverBase que es la que proporciona todos los métodos que normalmente sobreescribiremos en nuestros manejadores. En SharePoint vamos a tener dos tipos de manejadores de eventos:

  • Los denominados síncronos o “Before”:
    • Aquellos que tienen lugar antes de que ocurra un evento y que por lo tanto son útiles para realizar validaciones, chequeos o cancelaciones antes de que SharePoint escriba información en la BD de contenidos.
    • Estos eventos  se ejecutan en el mismo thread que la acción actual.
  • Los asíncronos o After”:
    • Aquellos que ocurren después de que SharePoint haga un “commit” de los datos en la BD de contenidos de manera que la operación no puede ser cancelada.
    • En este caso, la ejecución se realiza en otro thread respecto a la acción actual aunque es posible forzar una ejecución síncrona jugando con la propiedad Synchronization.

Publicado 21/10/2011 19:11 por Juan Carlos González Martín | 1 comment(s)

SharePoint 2010: Anatomía de un proyecto de WebPart en VS 2010!

Sin duda, a la hora de crear artefactos para SharePoint 2010 como WebParts, manejadores de eventos, etc la ayuda que nos brindan las Visual Studio 2010 Tools para SharePoint es fundamental. Ahora bien, aunque el uso de las herramientas nos ahorre mucho trabajo y simplifique las tareas a realizar es importante tener una idea clara de lo que estamos haciendo y saber que elementos forman parte de uno de estos artefactos. Cuando añadimos un elemento de tipo WebPart por ejemplo en un proyecto de Visual Studio para SharePoint, automáticamente se crea un SPI o SharePoint Project Item que contiene los elementos mínimos para poder desplegar una WebPart en nuestros sitios de SharePoint y que esté plenamente operativa:

image

  • Archivo de manifiesto, clave en este caso para provisionar el archivo .webpart que contiene toda la definición de una WebPart como el título, la descripción, etc. En este archivo son destacables:
    • La declaración del tipo .NET que se corresponde con la WebPart (definido en <metaData>) que en este caso está definido como un nombre completo (Full name) a través de la propiedad name que en este caso tiene el valor SPLINQWP.SPLINQToSPCRWP.SPLINQToSPCRP junto con el nombre del ensamblado que se especifica mediante $SharePoint.Project.AssemblyFullName$ que es automáticamente reemplazado por VS 2010 por el nombre del ensamblado durante el proceso de despliegue.
   1: <?xml version="1.0" encoding="utf-8"?>
   2: <webParts>
   3:   <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
   4:     <metaData>
   5:       <type name="SPLINQWP.SPLINQToSPCRWP.SPLINQToSPCRWP, $SharePoint.Project.AssemblyFullName$" />
   6:       <importErrorMessage>$Resources:core,ImportErrorMessage;</importErrorMessage>
   7:     </metaData>
   8:     <data>
   9:       <properties>
  10:           <property name="ChromeType" type="chrometype">TitleAndBorder</property>
  11:           <property name="Title" type="string">LINQ To SharePoint WP</property>
  12:           <property name="TitleIconImageUrl" type="string">_layouts/images/SPLINQWP/Feature_Icon_2.jpg</property>
  13:           <property name="Description" type="string">LINQ To SharePoint WebPart</property>
  14:           <property name="CatalogIconImageUrl" type="string">_layouts/images/SPLINQWP/Feature_Icon_2.jpg</property>
  15:           <property name="AllowEdit" type="bool">True</property>
  16:           <property name="AllowClose" type="bool">False</property>
  17:           <property name="AllowHide" type="bool">False</property>
  18:           <property name="AllowMinimize" type="bool">False</property>
  19:           <property name="AllowZoneChange" type="bool">False</property>
  20:           <property name="AllowConnect" type="bool">False</property>
  21:           <property name="ExportMode" type="exportmode">All</property>
  22:       </properties>
  23:     </data>
  24:   </webPart>
  25: </webParts>
  • Archivo de manifiesto “Elements.xml” en el que definimos como vamos a provisionar la WebPart. Más en concreto, como vamos a provisionar el archivo .webpart anterior en la galería de webparts y también en qué categoría se va a ubicar:
   1: <?xml version="1.0" encoding="utf-8"?>
   2: <Elements xmlns="http://schemas.microsoft.com/sharepoint/" >
   3:   <Module Name="SPLINQToSPCRWP" List="113" Url="_catalogs/wp">
   4:     <File Path="SPLINQToSPCRWP\SPLINQToSPCRWP.webpart" Url="SPLINQToSPCRWP.webpart" Type="GhostableInLibrary" >
   5:       <Property Name="Group" Value="BootCamp Costa Rica" />
   6:     </File>
   7:   </Module>
   8: </Elements>
  • Una clase que representa a la WebPart y que hereda de la clase base WebPart que como tal modela un control personalizado de ASP.NET. La definición de esta clase, para una WebPart de tipo clásico o una WebPart de tipo visual es como sigue:
   1: using System;
   2: using System.ComponentModel;
   3: using System.Web;
   4: using System.Web.UI;
   5: using System.Web.UI.WebControls;
   6: using System.Web.UI.WebControls.WebParts;
   7: using Microsoft.SharePoint;
   8: using Microsoft.SharePoint.WebControls;
   9:  
  10: namespace SPLINQWP.SPLINQToSPCRWP
  11: {
  12:     [ToolboxItemAttribute(false)]
  13:     public class SPLINQToSPCRWP : WebPart
  14:     {
  15:         // Visual Studio might automatically update this path when you change the Visual Web Part project item.
  16:         private const string _ascxPath = @"~/_CONTROLTEMPLATES/SPLINQWP/SPLINQToSPCRWP/SPLINQToSPCRWPUserControl.ascx";
  17:  
  18:         protected override void CreateChildControls()
  19:         {
  20:             Control control = Page.LoadControl(_ascxPath);
  21:             Controls.Add(control);
  22:         }
  23:     }
  24: }
  • Como vemos, uno de los puntos clave de la clase es la sobreescritura del método CreateChildControls() que como en cualquier control ASP.NET nos permite definir los controles web que constituyen la WebPart. En este caso, al tratarse de una WebPart visual tendremos un control definido a partir del user control que constituye la parte visual de la WebPart.
  • Un archivo de tipo user control para el caso de WebParts visuales.

Hasta aquí los elementos clave que forman parte de la WebPart a desplegar…pero, ¿cómo se despliega y hace disponible esta WebPart? Pues a través del correspondiente .WSP y de la correspondiente feature:

  • Si examinamos de nuevo la solución creada en Visual Studio 2010 veremos que tenemos un nodo Package en el que se define la plantilla del .WSP a generar. Es en esta definición dónde se indica que la WebPart se empaqueta como un .WSP indicando aspectos como:
    • La ubicación de despliegue de la WebPart (en este caso la GAC o Global Assembly Cache)
    • El “nombre fuerte” o strong name del ensamblado: nombre, versión, cultura y PublicKeyToken. Este strong name es el que permite añadir el ensamblado como un control seguro,
  • Y todo esto lo hace Visual Studio 2010 automáticamente por nosotros:
   1: <Solution xmlns="http://schemas.microsoft.com/sharepoint/" SolutionId="7ea4b87f-de64-46ec-9208-ac5b11d184b3" SharePointProductVersion="14.0">
   2:   <Assemblies>
   3:     <Assembly Location="SPLINQWP.dll" DeploymentTarget="GlobalAssemblyCache">
   4:       <SafeControls>
   5:         <SafeControl Assembly="SPLINQWP, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2ebe5d86e0efc3de" Namespace="SPLINQWP.SPLINQToSPCRWP" TypeName="*" />
   6:       </SafeControls>
   7:     </Assembly>
   8:   </Assemblies>
   9:   <TemplateFiles>
  10:     <TemplateFile Location="CONTROLTEMPLATES\SPLINQWP\SPLINQToSPCRWP\SPLINQToSPCRWPUserControl.ascx" />
  11:     <TemplateFile Location="Images\SPLINQWP\Feature_Icon_2.jpg" />
  12:   </TemplateFiles>
  13:   <FeatureManifests>
  14:     <FeatureManifest Location="SPLINQWP_SPLINQToSharePointWPFeature\Feature.xml" />
  15:   </FeatureManifests>
  16: </Solution>
  • La correspondiente Feature o Característica cuya activación hace posible que dispongamos de la WebPart para poder usar en nuestros sitios. Esta característica define la ubicación del archivo de manifiesto de la WebPart y del archivo .webpart.
   1: <Feature xmlns="http://schemas.microsoft.com/sharepoint/" Title="SP LINQ To SharePoint WebPart" Description="SP LINQ To SharePoint WebPart" Id="1e918292-9c18-4d06-9ede-b079d6e017ae" ImageUrl="SPLINQWP/Feature_Icon_2.jpg" Scope="Site">
   2:   <ElementManifests>
   3:     <ElementManifest Location="SPLINQToSPCRWP\Elements.xml" />
   4:     <ElementFile Location="SPLINQToSPCRWP\SPLINQToSPCRWP.webpart" />
   5:   </ElementManifests>
   6: </Feature>
image image

Publicado 20/10/2011 15:19 por Juan Carlos González Martín | con no comments

SharePoint 2010: Definiciones de sitios (I)!

Como ya comenté en este post, una de las posibilidades que tenemos en SharePoint 2010 para crear sitios es la de utilizar las definiciones de sitios disponibles por defecto en nuestra instalación o bien crear definiciones personalizadas. Lo primero que tenemos que saber antes de pasar a la creación de una definición de sitio personalizada es dónde se encuentran las disponibles por defecto. Estas se encuentran en bajo la ruta ..\14\TEMPLATE\SiteTemplates dónde encontraremos una carpeta por cada definición o grupo de definiciones disponibles que sigue la estructura que tenemos a la hora de crear visualmente sitios en base a las mismas:

  • Si navegamos hacía esa ruta, localizaremos fácilmente esa estructura en la ruta comentada.
  • Estas definiciones son las que luego nos permiten crear sitios en base a las mismas como se ha comentado.
  • Si entramos en una de las carpetas contenidas en SiteTemplates, por ejemplo la carpeta sts (SharePoint Team Site) veremos que contiene una serie de archivos (páginas, imágenes) y al menos una carpeta denominada XML que contiene un archivo XML clave para toda definición de sitio: ONET.xml.
image image image
  • Este archivo ONET.xml es el que define la configuración relativa a los elementos que forman parte del sitio que se cree en base a esta definición: características, módulos, plantillas de documentos, etc. En el caso de la definición STS el XML correspondiente es como sigue:
   1: <?xml version="1.0" encoding="utf-8"?>
   2: <Project Title="$Resources:onet_TeamWebSite;" Revision="2" ListDir="$Resources:core,lists_Folder;" xmlns:ows="Microsoft SharePoint" UIVersion="4">
   3:   <NavBars>
   4:     <NavBar Name="$Resources:core,category_Top;" Separator="&amp;nbsp;&amp;nbsp;&amp;nbsp;" Body="&lt;a ID='onettopnavbar#LABEL_ID#' href='#URL#' accesskey='J'&gt;#LABEL#&lt;/a&gt;" ID="1002" />
   5:     <NavBar Name="$Resources:core,category_Documents;" Prefix="&lt;table border='0' cellpadding='4' cellspacing='0'&gt;" Body="&lt;tr&gt;&lt;td&gt;&lt;table border='0' cellpadding='0' cellspacing='0'&gt;&lt;tr&gt;&lt;td&gt;&lt;img src='/_layouts/images/blank.gif' id='100' alt='' border='0'&gt;&amp;nbsp;&lt;/td&gt;&lt;td valign='top'&gt;&lt;a id='onetleftnavbar#LABEL_ID#' href='#URL#'&gt;#LABEL#&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;" Suffix="&lt;/table&gt;" ID="1004" />
   6:     <NavBar Name="$Resources:core,category_Lists;" Prefix="&lt;table border='0' cellpadding='4' cellspacing='0'&gt;" Body="&lt;tr&gt;&lt;td&gt;&lt;table border='0' cellpadding='0' cellspacing='0'&gt;&lt;tr&gt;&lt;td&gt;&lt;img src='/_layouts/images/blank.gif' id='100' alt='' border='0'&gt;&amp;nbsp;&lt;/td&gt;&lt;td valign='top'&gt;&lt;a id='onetleftnavbar#LABEL_ID#' href='#URL#'&gt;#LABEL#&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;" Suffix="&lt;/table&gt;" ID="1003" />
   7:     <NavBar Name="$Resources:core,category_Discussions;" Prefix="&lt;table border='0' cellpadding='4' cellspacing='0'&gt;" Body="&lt;tr&gt;&lt;td&gt;&lt;table border='0' cellpadding='0' cellspacing='0'&gt;&lt;tr&gt;&lt;td&gt;&lt;img src='/_layouts/images/blank.gif' id='100' alt='' border='0'&gt;&amp;nbsp;&lt;/td&gt;&lt;td valign='top'&gt;&lt;a id='onetleftnavbar#LABEL_ID#' href='#URL#'&gt;#LABEL#&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;" Suffix="&lt;/table&gt;" ID="1006" />
   8:   </NavBars>
   9:   <ListTemplates>
  10:   </ListTemplates>
  11:   <DocumentTemplates>
  12:     <DocumentTemplate Path="STS" Name="" DisplayName="$Resources:core,doctemp_None;" Type="100" Default="FALSE" Description="$Resources:core,doctemp_None_Desc;" />
  13:     <DocumentTemplate Path="STS" DisplayName="$Resources:core,doctemp_Word97;" Type="101" Description="$Resources:core,doctemp_Word97_Desc;">
  14:       <DocumentTemplateFiles>
  15:         <DocumentTemplateFile Name="doctemp\word\wdtmpl.doc" TargetName="Forms/template.doc" Default="TRUE" />
  16:       </DocumentTemplateFiles>
  17:     </DocumentTemplate>
  18:     <DocumentTemplate Path="STS" DisplayName="$Resources:core,doctemp_Excel97;" Type="103" Description="$Resources:core,doctemp_Excel97_Desc;">
  19:       <DocumentTemplateFiles>
  20:         <DocumentTemplateFile Name="doctemp\xl\xltmpl.xls" TargetName="Forms/template.xls" Default="TRUE" />
  21:       </DocumentTemplateFiles>
  22:     </DocumentTemplate>
  23:     <DocumentTemplate Path="STS" DisplayName="$Resources:core,doctemp_Powerpoint97;" Type="104" Description="$Resources:core,doctemp_Powerpoint97_Desc;">
  24:       <DocumentTemplateFiles>
  25:         <DocumentTemplateFile Name="doctemp\ppt\pptmpl.pot" TargetName="Forms/template.pot" Default="TRUE" />
  26:       </DocumentTemplateFiles>
  27:     </DocumentTemplate>
  28:     <DocumentTemplate Path="STS" DisplayName="$Resources:core,doctemp_Word;" Type="121" Default="TRUE" Description="$Resources:core,doctemp_Word_Desc;">
  29:       <DocumentTemplateFiles>
  30:         <DocumentTemplateFile Name="doctemp\word\wdtmpl.dotx" TargetName="Forms/template.dotx" Default="TRUE" />
  31:       </DocumentTemplateFiles>
  32:     </DocumentTemplate>
  33:     <DocumentTemplate Path="STS" DisplayName="$Resources:core,doctemp_Excel;" Type="122" Description="$Resources:core,doctemp_Excel_Desc;">
  34:       <DocumentTemplateFiles>
  35:         <DocumentTemplateFile Name="doctemp\xl\xltmpl.xlsx" TargetName="Forms/template.xlsx" Default="TRUE" />
  36:       </DocumentTemplateFiles>
  37:     </DocumentTemplate>
  38:     <DocumentTemplate Path="STS" DisplayName="$Resources:core,doctemp_Powerpoint;" Type="123" Description="$Resources:core,doctemp_Powerpoint_Desc;">
  39:       <DocumentTemplateFiles>
  40:         <DocumentTemplateFile Name="doctemp\ppt\pptmpl.pptx" TargetName="Forms/template.pptx" Default="TRUE" />
  41:       </DocumentTemplateFiles>
  42:     </DocumentTemplate>
  43:     <DocumentTemplate Path="STS" DisplayName="$Resources:core,doctemp_OneNote;" Type="111" Description="$Resources:core,doctemp_OneNote_Desc;">
  44:       <DocumentTemplateFiles>
  45:         <DocumentTemplateFile Name="doctemp\onenote\template.onepkg" TargetName="Forms/template.onepkg" Default="TRUE" />
  46:       </DocumentTemplateFiles>
  47:     </DocumentTemplate>
  48:     <DocumentTemplate Path="STS" DisplayName="$Resources:core,doctemp_FP;" Type="102" Description="$Resources:core,doctemp_FP_Desc;">
  49:       <DocumentTemplateFiles>
  50:         <DocumentTemplateFile Name="doctemp\fp\fptmpl.htm" TargetName="Forms/template.htm" Default="TRUE" />
  51:       </DocumentTemplateFiles>
  52:     </DocumentTemplate>
  53:     <DocumentTemplate Path="STS" DisplayName="$Resources:core,doctemp_BasicPage;" Type="105" Description="$Resources:core,doctemp_BasicPage_Desc;">
  54:       <DocumentTemplateFiles>
  55:         <DocumentTemplateFile Name="doctemp\blankpgs\_basicpage.htm" TargetName="Forms/_basicpage.htm" Default="TRUE" />
  56:       </DocumentTemplateFiles>
  57:     </DocumentTemplate>
  58:     <DocumentTemplate Path="STS" DisplayName="$Resources:core,doctemp_WebPartPage;" Type="106" Description="$Resources:core,doctemp_WebPartPage_Desc;">
  59:       <DocumentTemplateFiles>
  60:         <DocumentTemplateFile Name="doctemp\smartpgs\_webpartpage.htm" TargetName="Forms/_webpartpage.htm" Default="TRUE" />
  61:       </DocumentTemplateFiles>
  62:     </DocumentTemplate>
  63:     <DocumentTemplate XMLForm="TRUE" Path="STS" DisplayName="$Resources:core,doctemp_BlankForm;" Type="1000" Default="TRUE" Description="$Resources:core,doctemp_BlankForm_Desc;">
  64:       <DocumentTemplateFiles>
  65:         <DocumentTemplateFile Name="doctemp\xmlforms\blank\template.xml" TargetName="Forms/template.xml" Default="TRUE" />
  66:       </DocumentTemplateFiles>
  67:     </DocumentTemplate>
  68:   </DocumentTemplates>
  69:   <Configurations>
  70:     <Configuration ID="-1" Name="NewWeb" MasterUrl="_catalogs/masterpage/v4.master" />
  71:     <Configuration ID="0" Name="Default" MasterUrl="_catalogs/masterpage/v4.master">
  72:       <Lists>
  73:         <List FeatureId="00BFEA71-E717-4E80-AA17-D0C71B360101" Type="101" Title="$Resources:core,shareddocuments_Title;" Url="$Resources:core,shareddocuments_Folder;" QuickLaunchUrl="$Resources:core,shareddocuments_Folder;/Forms/AllItems.aspx" />
  74:         <List FeatureId="00BFEA71-6A49-43FA-B535-D15C05500108" Type="108" Title="$Resources:core,discussions_Title;" Url="$Resources:core,lists_Folder;/$Resources:core,discussions_Folder;" QuickLaunchUrl="$Resources:core,lists_Folder;/$Resources:core,discussions_Folder;/AllItems.aspx" EmailAlias="$Resources:core,discussions_EmailAlias;" />
  75:         <List FeatureId="00BFEA71-D1CE-42de-9C63-A44004CE0104" Type="104" Title="$Resources:core,announceList;" Url="$Resources:core,lists_Folder;/$Resources:core,announce_Folder;">
  76:           <Data>
  77:             <Rows>
  78:               <Row>
  79:                 <Field Name="Title">$Resources:onetid11;</Field>
  80:                 <Field Name="Body">$Resources:onetid12;</Field>
  81:                 <Field Name="Expires">&lt;ows:TodayISO/&gt;</Field>
  82:               </Row>
  83:             </Rows>
  84:           </Data>
  85:         </List>
  86:         <List FeatureId="00BFEA71-2062-426C-90BF-714C59600103" Type="103" Title="$Resources:core,linksList;" Url="$Resources:core,lists_Folder;/$Resources:core,links_Folder;" />
  87:         <List FeatureId="00BFEA71-EC85-4903-972D-EBE475780106" Type="106" Title="$Resources:core,calendarList;" Url="$Resources:core,lists_Folder;/$Resources:core,calendar_Folder;" QuickLaunchUrl="$Resources:core,lists_Folder;/$Resources:core,calendar_Folder;/Calendar.aspx" EmailAlias="$Resources:core,calendar_EmailAlias;" />
  88:         <List FeatureId="00BFEA71-A83E-497E-9BA0-7A5C597D0107" Type="107" Title="$Resources:core,taskList;" Url="$Resources:core,lists_Folder;/$Resources:core,tasks_Folder;" QuickLaunchUrl="$Resources:core,lists_Folder;/$Resources:core,tasks_Folder;/AllItems.aspx" />
  89:       </Lists>
  90:       <Modules>
  91:         <Module Name="Default" />
  92:       </Modules>
  93:       <SiteFeatures>
  94:         <!-- BasicWebParts Feature -->
  95:         <Feature ID="00BFEA71-1C5E-4A24-B310-BA51C3EB7A57" />
  96:         <!-- Three-state Workflow Feature -->
  97:         <Feature ID="FDE5D850-671E-4143-950A-87B473922DC7" />
  98:       </SiteFeatures>
  99:       <WebFeatures>
 100:         <!-- TeamCollab Feature -->
 101:         <Feature ID="00BFEA71-4EA5-48D4-A4AD-7EA5C011ABE5" />
 102:         <!-- MobilityRedirect -->
 103:         <Feature ID="F41CC668-37E5-4743-B4A8-74D1DB3FD8A4" />
 104:         <!-- WikiPageHomePage Feature -->
 105:         <Feature ID="00BFEA71-D8FE-4FEC-8DAD-01C19A6E4053" />
 106:       </WebFeatures>
 107:     </Configuration>
 108:     <Configuration ID="1" Name="Blank" MasterUrl="_catalogs/masterpage/v4.master">
 109:       <Lists />
 110:       <Modules>
 111:         <Module Name="DefaultBlank" />
 112:       </Modules>
 113:       <SiteFeatures>
 114:         <!-- BasicWebParts Feature -->
 115:         <Feature ID="00BFEA71-1C5E-4A24-B310-BA51C3EB7A57" />
 116:         <!-- Three-state Workflow Feature -->
 117:         <Feature ID="FDE5D850-671E-4143-950A-87B473922DC7" />
 118:       </SiteFeatures>
 119:       <WebFeatures>
 120:         <!-- TeamCollab Feature -->
 121:         <Feature ID="00BFEA71-4EA5-48D4-A4AD-7EA5C011ABE5" />
 122:         <!-- MobilityRedirect -->
 123:         <Feature ID="F41CC668-37E5-4743-B4A8-74D1DB3FD8A4" />
 124:       </WebFeatures>
 125:     </Configuration>
 126:     <Configuration ID="2" Name="DWS" MasterUrl="_catalogs/masterpage/v4.master">
 127:       <Lists>
 128:         <List FeatureId="00BFEA71-E717-4E80-AA17-D0C71B360101" Type="101" Title="$Resources:core,shareddocuments_Title;" Url="$Resources:core,shareddocuments_Folder;" />
 129:         <List FeatureId="00BFEA71-6A49-43FA-B535-D15C05500108" Type="108" Title="$Resources:core,discussions_Title;" Url="$Resources:core,lists_Folder;/$Resources:core,discussions_Folder;" QuickLaunchUrl="$Resources:core,lists_Folder;/$Resources:core,discussions_Folder;" />
 130:         <List FeatureId="00BFEA71-D1CE-42de-9C63-A44004CE0104" Type="104" Title="$Resources:core,announceList;" Url="$Resources:core,lists_Folder;/$Resources:core,announce_Folder;">
 131:           <Data>
 132:             <Rows>
 133:               <Row>
 134:                 <Field Name="Title">$Resources:onetid11;</Field>
 135:                 <Field Name="Body">$Resources:onetid12;</Field>
 136:                 <Field Name="Expires">&lt;ows:TodayISO/&gt;</Field>
 137:               </Row>
 138:             </Rows>
 139:           </Data>
 140:         </List>
 141:         <List FeatureId="00BFEA71-2062-426C-90BF-714C59600103" Type="103" Title="$Resources:core,linksList;" Url="$Resources:core,lists_Folder;/$Resources:core,links_Folder;" />
 142:         <List FeatureId="00BFEA71-EC85-4903-972D-EBE475780106" Type="106" Title="$Resources:core,calendarList;" Url="$Resources:core,lists_Folder;/$Resources:core,calendar_Folder;" QuickLaunchUrl="$Resources:core,lists_Folder;/$Resources:core,calendar_Folder;/Calendar.aspx" />
 143:         <List FeatureId="00BFEA71-A83E-497E-9BA0-7A5C597D0107" Type="107" Title="$Resources:core,taskList;" Url="$Resources:core,lists_Folder;/$Resources:core,tasks_Folder;" />
 144:       </Lists>
 145:       <Modules>
 146:         <Module Name="DWS" />
 147:       </Modules>
 148:       <SiteFeatures>
 149:         <!-- BasicWebParts Feature -->
 150:         <Feature ID="00BFEA71-1C5E-4A24-B310-BA51C3EB7A57" />
 151:         <!-- Three-state Workflow Feature -->
 152:         <Feature ID="FDE5D850-671E-4143-950A-87B473922DC7" />
 153:       </SiteFeatures>
 154:       <WebFeatures>
 155:         <!-- TeamCollab Feature -->
 156:         <Feature ID="00BFEA71-4EA5-48D4-A4AD-7EA5C011ABE5" />
 157:         <!-- MobilityRedirect -->
 158:         <Feature ID="F41CC668-37E5-4743-B4A8-74D1DB3FD8A4" />
 159:       </WebFeatures>
 160:     </Configuration>
 161:   </Configurations>
 162:   <Modules>
 163:     <Module Name="Default" Url="" Path="">
 164:       <File Url="default.aspx" NavBarHome="True">
 165:         <View List="$Resources:core,lists_Folder;/$Resources:core,announce_Folder;" BaseViewID="0" MobileView="TRUE" WebPartZoneID="Left" />
 166:         <View List="$Resources:core,lists_Folder;/$Resources:core,calendar_Folder;" BaseViewID="0" MobileView="TRUE" RecurrenceRowset="TRUE" WebPartZoneID="Left" WebPartOrder="2" />
 167:         <View List="$Resources:core,lists_Folder;/$Resources:core,links_Folder;" BaseViewID="0" MobileView="TRUE" WebPartZoneID="Right" WebPartOrder="1" />
 168:         <NavBarPage Name="$Resources:core,nav_Home;" Url="~site" ID="1002" Position="Start" />
 169:         <NavBarPage Name="$Resources:core,nav_Home;" Url="" ID="0" Position="Start" />
 170:       </File>
 171:     </Module>
 172:     <Module Name="DefaultBlank" Url="" Path="">
 173:       <File Url="default.aspx" NavBarHome="True" Type="Ghostable">
 174:         <NavBarPage Name="$Resources:core,nav_Home;" Url="~site" ID="1002" Position="Start" />
 175:         <NavBarPage Name="$Resources:core,nav_Home;" Url="" ID="0" Position="Start" />
 176:       </File>
 177:     </Module>
 178:     <Module Name="DWS" Url="">
 179:       <File Url="defaultdws.aspx" Name="default.aspx">
 180:         <View List="$Resources:core,lists_Folder;/$Resources:core,announce_Folder;" BaseViewID="0" WebPartZoneID="Top" />
 181:         <View List="$Resources:core,lists_Folder;/$Resources:core,links_Folder;" BaseViewID="0" WebPartZoneID="Right" WebPartOrder="2" />
 182:         <View List="$Resources:core,shareddocuments_Folder;" BaseViewID="1" WebPartZoneID="Left" />
 183:         <View List="$Resources:core,lists_Folder;/$Resources:core,tasks_Folder;" BaseViewID="7" WebPartZoneID="Left" WebPartOrder="2" />
 184:         <AllUsersWebPart WebPartZoneID="Right" WebPartOrder="1"><![CDATA[
 185:                    <WebPart xmlns="http://schemas.microsoft.com/WebPart/v2">
 186:                       <Assembly>Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
 187:                       <TypeName>Microsoft.SharePoint.WebPartPages.MembersWebPart</TypeName>
 188:                       <Title>$Resources:wp_Members;</Title>
 189:                       <Description>$Resources:wp_Members_Desc;</Description>
 190:                       <FrameType>Standard</FrameType>
 191:                       <IsVisible>true</IsVisible>
 192:                       </WebPart>
 193:                    ]]></AllUsersWebPart>
 194:         <NavBarPage Name="$Resources:core,nav_Home;" Url="~site" ID="1002" Position="Start" />
 195:         <NavBarPage Name="$Resources:core,nav_Home;" ID="0" Position="Start" />
 196:       </File>
 197:     </Module>
 198:   </Modules>
 199:   <ServerEmailFooter>$Resources:ServerEmailFooter;</ServerEmailFooter>
 200: </Project>

Pero, ¿Cómo hace uso SharePoint de este archivo ONET.xml para que se puedan crear sitios en base al mismo? Básicamente, SharePoint lo que hace es leer la lista de definiciones disponibles de un archivo de la forma WEBTEMP*.xml que se encuentra ubicado en la ruta ..\14\TEAMPATE\<Código_Cultura>\XML. Por ejemplo, para la cultura 3082 (castellano), y dependiendo de los componentes instalados, el contenido de dicha carpeta será como sigue:

image

Si editamos el archivo WEBTEMP.xml veremos en su contenido lo siguiente:

  • Una enumeración de las definiciones disponibles, especificando para cada una el nombre, descripción, identificador, etc.
   1: <?xml version="1.0" encoding="utf-8"?>
   2: <!-- _lcid="3082" _version="14.0.4762" _dal="1" -->
   3: <!-- _LocalBinding -->
   4: <Templates xmlns:ows="Microsoft SharePoint">
   5:  <Template Name="GLOBAL" SetupPath="global" ID="0">
   6:     <Configuration ID="0" Title="Plantilla global" Hidden="TRUE" ImageUrl="" Description="Esta plantilla se usa inicializar un sitio nuevo." >   </Configuration>
   7:  </Template>
   8:  <Template Name="STS" ID="1">
   9:     <Configuration ID="0" Title="Sitio de grupo" Hidden="FALSE" ImageUrl="/_layouts/images/stts.png" Description="Sitio para que los grupos organicen, creen y compartan información con rapidez. Proporciona una biblioteca de documentos y listas para la administración de anuncios, elementos de calendario, tareas y discusiones." DisplayCategory="Colaboración" >    </Configuration>
  10:     <Configuration ID="1" Title="Sitio en blanco" Hidden="FALSE" ImageUrl="/_layouts/images/stbs.png" Description="Sitio en blanco para que lo personalice en función de sus necesidades." DisplayCategory="Colaboración" AllowGlobalFeatureAssociations="False" >    </Configuration>
  11:     <Configuration ID="2" Title="Área de documentos" Hidden="FALSE" ImageUrl="/_layouts/images/stdw.png" Description="Sitio para que varios compañeros puedan trabajar en un documento. Proporciona una biblioteca de documentos para almacenar el documento y los archivos auxiliares, una lista de tareas para la asignación de elementos pendientes y una lista de vínculos para los recursos relacionados con el documento." DisplayCategory="Colaboración" >    </Configuration>
  12:  </Template>
  13:  <Template Name="MPS" ID="2">
  14:     <Configuration ID="0" Title="Área de reuniones básica" Hidden="FALSE" ImageUrl="/_layouts/images/stmw.png" Description="Sitio para planear, organizar y capturar los resultados de una reunión. Proporciona listas para la administración de la agenda, los asistentes a la reunión y los documentos." DisplayCategory="Reuniones" SupportsMultilingualUI="FALSE" >    </Configuration>
  15:     <Configuration ID="1" Title="Área de reuniones en blanco" Hidden="FALSE" ImageUrl="/_layouts/images/stbm.png" Description="Sitio de reuniones en blanco para que la personalice en función de sus necesidades." DisplayCategory="Reuniones" SupportsMultilingualUI="FALSE" >    </Configuration>
  16:     <Configuration ID="2" Title="Área de toma de decisiones" Hidden="FALSE" ImageUrl="/_layouts/images/stdm.png" Description="Sitios para reuniones en las que se efectúa el seguimiento del estado o se toman decisiones. Proporciona listas para la creación de tareas, el almacenamiento de documentos y el registro de decisiones." DisplayCategory="Reuniones" SupportsMultilingualUI="FALSE" >    </Configuration>
  17:     <Configuration ID="3" Title="Área de reuniones sociales" Hidden="FALSE" ImageUrl="/_layouts/images/stsm.png" Description="Sitio para planificar reuniones sociales. Proporciona listas para efectuar el seguimiento de asistentes, dar instrucciones y almacenar fotos del acontecimiento." DisplayCategory="Reuniones" SupportsMultilingualUI="FALSE" >    </Configuration>
  18:     <Configuration ID="4" Title="Área de reuniones de varias páginas" Hidden="FALSE" ImageUrl="/_layouts/images/stmm.png" Description="Sitio para planear, organizar y capturar los resultados de una reunión. Proporciona listas para la administración de la agenda y los asistentes a la reunión, así como dos páginas en blanco que puede personalizar según sus necesidades." DisplayCategory="Reuniones" SupportsMultilingualUI="FALSE" >    </Configuration>
  19:  </Template>
  20:  <Template Name="CENTRALADMIN" ID="3">
  21:     <Configuration ID="0" Title="Sitio de administración central" Hidden="TRUE" ImageUrl="" Description="Sitio para la administración central. Proporciona páginas y vínculos web para la administración de aplicaciones y operaciones." >   </Configuration>
  22:  </Template>
  23:  <Template Name="WIKI" ID="4">
  24:     <Configuration ID="0" Title="Sitio Wiki" Hidden="TRUE" ImageUrl="/_layouts/images/wikiprev.png" Description="Sitio para el intercambio de ideas entre los miembros de una comunidad. Proporciona páginas web que pueden modificarse con facilidad para registrar información y, a continuación, vincularse entre sí mediante palabras clave" DisplayCategory="Colaboración" >    </Configuration>
  25:  </Template>
  26:  <Template Name="BLOG" ID="9">
  27:     <Configuration ID="0" Title="Blog" Hidden="FALSE" ImageUrl="/_layouts/images/stbg.png" Description="Sitio para que una persona o grupo exponga ideas, observaciones y conocimientos a los que los visitantes del sitio pueden hacer comentarios." DisplayCategory="Colaboración" SupportsMultilingualUI="FALSE" >    </Configuration>
  28:  </Template>
  29:  <Template Name="SGS" SetupPath="SiteTemplates\sgs" ID="15">
  30:     <Configuration ID="0" Title="Sitio de grupo de trabajo" Hidden="FALSE" ImageUrl="/_layouts/images/stgb.png" Description="Esta plantilla proporciona una solución de groupware que permite a los equipos crear, organizar y compartir información rápida y fácilmente. Incluye Calendario del grupo, Circulación, Memo de llamadas de teléfono, Biblioteca de documentos y las otras listas básicas." DisplayCategory="Colaboración" >    </Configuration>
  31:  </Template>
  32:  <Template Name="TENANTADMIN" SetupPath="SiteTemplates\tenantadmin" ID="16">
  33:     <Configuration ID="0" Title="Sitio de administración de inquilinos" Hidden="TRUE" ImageUrl="" Description="Sitio para la administración de inquilinos. Proporciona páginas web y vínculos para la administración sin intervención del administrador." >   </Configuration>
  34:  </Template>
  35: </Templates>
  • Como vemos, el archivo contiene una serie de elementos de tipo <Template> que a su vez pueden disponer de uno o más elementos hijos de tipo <Configuration>, de manera que dada una definición podremos tener varias configuraciones posibles. El ejemplo más claro lo tenemos para el caso de un sitio de tipo STS que admite tres configuraciones: “Sitio de grupo”, “Sitio en blanco” o “Área de documentos” lo que traducido en configuración interna nos lleva a hablar de STS#0, STS#1 y STS#2. Ese identificador será el que usemos para crear una colección de sitios por ejemplo mediante el modelo de objetos:
   1: SPWebApplication spwAplicacionWeb=
   2:     SPWebApplication.Lookup(
   3:         new Uri("http://MiAppWeb:100/"));
   4: SPSite spsColeccionSitios = 
   5:     spwAplicacionWeb.Sites.Add(
   6:     "/sitios/IT", 
   7:     "IT", 
   8:     "Sitio del departamento de IT",
   9:     Convert.ToUInt32(3082), "STS#0",
  10:     “dominio\\Administrator", dominio\\Administrator", "Administrador@organizacion.com");
  11:     "
  12: spsColeccionSitios.Dispose();
  • WEBTEMP.xml enumera las definiciones y en los respectivos archivos ONET.xml tendremos la configuración que aplica a cada una.

Finalmente, os dejo como listar las definiciones de sitios disponibles mediante PowerShell siguiendo este post de Waldek Mastukarz.

Publicado 19/10/2011 21:48 por Juan Carlos González Martín | 3 comment(s)

SharePoint 2010: Apertura de ventanas modales y páginas desde acciones personalizadas (II)!

Siguiendo con la serie de posts sobre como abrir ventanas modales  y páginas desde acciones personalizadas, en esta ocasión vamos a ver como crear estas acciones de forma declarativa. Básicamente, si queremos crear una acción personalizada para abrir una ventana modal crearemos un proyecto de tipo vacío en Visual Studio 2010 y le añadiremos un elemento de tipo vacío. Dicho elemento constará de un archivo elements.xml que configuraremos de acuerdo al siguiente código:

   1: <?xml version="1.0" encoding="UTF-8"?>
   2: <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
   3:     <CustomAction Location="CommandUI.Ribbon" RegistrationId="101" RegistrationType="List" Id="80AFCE46-0DD4-4A11-9B1B-9B8FBCD38AAD">    
   4:         <CommandUIExtension>
   5:         <CommandUIDefinitions>
   6:             <CommandUIDefinition Location="Ribbon.Documents.Manage.Controls._children">
   7:                     <Button Id="Ribbon.Documents.Manage.Controls.AbrirDialogoByCommandHandler" TemplateAlias="o1" LabelText="Abrir Diálogo" Image32by32="/_layouts/images/SPCAOpenDialog/open.gif" Command="OpenDialog" Sequence="1981"/>
   8:             </CommandUIDefinition>
   9:         </CommandUIDefinitions>                
  10:         <CommandUIHandlers>            
  11:             <CommandUIHandler Command="OpenDialog" CommandAction="BLOCKED SCRIPT
  12:                 function CallDETCustomDialog(dialogResult, returnValue)
  13:                 { 
  14:                     SP.UI.ModalDialog.RefreshPage(SP.UI.DialogResult.OK);
  15:                 }
  16:                 var options = {
  17:                     url: '{SiteUrl}' + '/Documentos%20compartidos/Forms/Todos%20los%20documentos.aspx',
  18:                     title: 'Detalle de elemento', 
  19:                     allowMaximize: false,
  20:                     showClose: true,
  21:                     width: 500, 
  22:                     height: 300,
  23:                     dialogReturnValueCallback: CallDETCustomDialog }; 
  24:                     SP.UI.ModalDialog.showModalDialog(options);">                
  25:             </CommandUIHandler>            
  26:             </CommandUIHandlers>
  27:         </CommandUIExtension>        
  28:     </CustomAction>
  29: </Elements>

Como vemos, lo más interesante en la acción es que podemos especificar como CommandAction un bloque de código JavaScript en el que levantemos una ventana modal. Si lo que queremos es hacer una redirección, simplemente especificamos la Url a la que qureemos ir en el CommandAction.

   1: <?xml version="1.0" encoding="UTF-8"?>
   2: <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
   3:     <CustomAction Location="CommandUI.Ribbon" RegistrationId="101" RegistrationType="List" Id="D6D6D9AE-64D6-4B26-96BF-B2F942260821">        
   4:         <CommandUIExtension>        
   5:             <CommandUIDefinitions>
   6:                 <CommandUIDefinition Location="Ribbon.Documents.Manage.Controls._children">
   7:                     <Button Id="Ribbon.Documents.Manage.Controls.AbrirDialogoByUrlAction" TemplateAlias="o1" LabelText="Abrir Diálogo (2)" Image32by32="/_layouts/images/SPCAOpenDialog/open.gif" Command="RedirectToPage" Sequence="1982"/>
   8:                 </CommandUIDefinition>
   9:             </CommandUIDefinitions>
  10:             <CommandUIHandlers>
  11:                 <CommandUIHandler Command="RedirectToPage" CommandAction="~site/Documentos%20compartidos/Forms/Todos%20los%20documentos.aspx?List={ListId}&amp;ID={ItemId}">
  12:                 </CommandUIHandler>
  13:             </CommandUIHandlers>
  14:         </CommandUIExtension>        
  15:     </CustomAction>
  16: </Elements>

Otros posts relacionados:

Algunas referencias:

Publicado 18/10/2011 21:27 por Juan Carlos González Martín | 2 comment(s)

Visual Studio 11: Disponible la release de octubre del training kit!

Ya tenemos disponible para descarga la primera release del training kit de octubre para Visual Studio 11. En la misma página os podréis descargar el kit junto con el Web Platform Installer Preview. En cuanto a contenido del training kit, el resumen es el siguiente (de los laboratorios incluidos):

  • Visual Studio Development Environment:
    • A Lap Around the Visual Studio 11 Development Environment.
  • Languages:
    • Asynchronous Programming in .NET 4.5 with C# and Visual Basic.
  • Web:
    • What's New in ASP.NET and Visual Studio 11 Developer Preview.
    • What's New in ASP.NET Web Forms 4.5.
    • Build RESTful APIs with WCF Web API.
  • Application Lifecycle Management:
    • Building the Right Software: Generating Storyboards and Collecting Stakeholder Feedback with Visual Studio 11.
    • Agile Project Management in Team Foundation Server 11.
    • Making Developers More Productive with Team Foundation Server 11.
    • Diagnosing Issues in Production with IntelliTrace and Visual Studio 11.
    • Exploratory Testing and Other Enhancements in Microsoft Test Manager 11.
    • Unit Testing with Visual Studio 11: MSTest, NUnit, xUnit.net, and Code Clone.
  • Windows Metro Style Apps:
    • Windows 8 Developer Preview Hands on Labs from BUILD.

image

Publicado 18/10/2011 8:25 por Juan Carlos González Martín | con no comments

Archivado en:

Office 365: ¿Tengo suficiente ancho de banda? (II)!

Siguiendo con el tema de como saber los requerimientos de ancho de banda mínimos para trabajar sin problemas con los servicios de Office 365 y ver si podemos tener problemas a este respecto, en esta ocasión os dejo un par de enlaces relativos a los requerimientos mínimos de ancho de banda para Lync los cuáles se deberían tener en cuenta a la hora de asegurar una productividad máxima cuando se vaya a utilizar Lync Online:

image

Publicado 17/10/2011 21:00 por Juan Carlos González Martín | 2 comment(s)

Archivado en:

SharePoint 2010: Como añadir “verbos” personalizados a una WebPart!

Las WebParts en SharePoint 2010, como casi toda la plataforma, son muy extensibles de manera que podemos añadir nuevas personalizaciones a distintos niveles: propiedades en la Toolpart, conexiones de Webparts, o verbos. Precisamente sobre estos últimos trata este post….¿Qué es un “verbo” en una WebPart? pues no es más qué cualquier opción de menú disponible en el menú contextual de la misma:

image

Para añadir nuevos “verbos” a una WebPart tenemos que sobreescribir la propiedad Verbs disponible en la clase base WebPart. Esta propiedad nos devuelveun WebPartVerbCollection teniendo en cuenta que tenemos tres tipos de verbos:

  • Del lado del servidor, es decir, se necesita hacer una petición al servidior.
  • Del lado del cliente, es decir, todo se hace en el cliente vía JavaScript.
  • Del lado del cliente y del lado del servidor, es decir, primero se ejecuta algo de trabajo en el cliente y luego algo en el servidor.

Dicho esto, para añadir nuestros verbos a la WebPart basta con sobreescribir la propiedad comentada como por ejemplo:

   1: using System;
   2: using System.ComponentModel;
   3: using System.Web;
   4: using System.Web.UI;
   5: using System.Web.UI.WebControls;
   6: using System.Web.UI.WebControls.WebParts;
   7: using Microsoft.SharePoint;
   8: using Microsoft.SharePoint.WebControls;
   9:  
  10: namespace SPLINQWP.SPLINQToSPCRWP
  11: {
  12:     [ToolboxItemAttribute(false)]
  13:     public class SPLINQToSPCRWP : WebPart
  14:     {
  15:         // Visual Studio might automatically update this path when you change the Visual Web Part project item.
  16:         private const string _ascxPath = @"~/_CONTROLTEMPLATES/SPLINQWP/SPLINQToSPCRWP/SPLINQToSPCRWPUserControl.ascx";
  17:         protected Label lblMessage;
  18:  
  19:         protected override void CreateChildControls()
  20:         {
  21:             Control control = Page.LoadControl(_ascxPath);
  22:             lblMessage = new Label();
  23:             Controls.Add(control);
  24:             Controls.Add(lblMessage);
  25:         }
  26:  
  27:         public override WebPartVerbCollection Verbs
  28:         {
  29:             get
  30:             {
  31:                 WebPartVerb ssWebPartVerb = new WebPartVerb("serverSiteVerbId", handlessWebPartVerb);
  32:                 ssWebPartVerb.Text = "Verbo en el lado del servidor";
  33:                 WebPartVerb csWebPartVerb = new WebPartVerb("clientSideVerbId", "BLOCKED SCRIPTalert('Has pulsado un verbo en el lado del cliente');");
  34:                 csWebPartVerb.Text = "Verbo en el lado del cliente";
  35:                 WebPartVerb cssWebPartVerb = new WebPartVerb("clientAndServerSideVerbId",
  36:                     handlessWebPartVerb, "BLOCKED SCRIPTalert('Has pulsado un verbo en el lado del cliente');"
  37:                     );
  38:                 cssWebPartVerb.Text = "Verbo en el lado del cliente y del servidor";
  39:                 WebPartVerbCollection wpvcColeccionVerbos= new WebPartVerbCollection(
  40:                     new WebPartVerb[] {
  41:                         ssWebPartVerb, csWebPartVerb, cssWebPartVerb,
  42:                     }
  43:                     );
  44:                 return (new WebPartVerbCollection(base.Verbs, wpvcColeccionVerbos));
  45:             }
  46:         }
  47:  
  48:  
  49:         protected void handlessWebPartVerb(Object source, WebPartEventArgs args)
  50:         {
  51:             EnsureChildControls();
  52:             this.lblMessage.Text = "Se ha realizado una llamada al servidor";
  53:         }
  54:     }
  55: }

Hacemos el despliegue de la WebPart y comprobamos:

  • Que los nuevos verbos están disponibles.
  • Que el verbo en el lado del cliente funciona como se ha configurado.
  • Que el verbo en el lado del servidor funciona también como se espera.

 

image image image

Publicado 16/10/2011 22:47 por Juan Carlos González Martín | 1 comment(s)

SharePoint 2010: Herramientas de desarrollo (I)!

Aunque a la hora de desarrollar para SharePoint 2010, tenemos un soporte mucho mayor que el que teníamos en SharePoint 2007, igualmente necesitaremos de otra serie de herramientas de desarrollo que complementen lo que tenemos en Visual Studio 2010. Por eso, siguiendo la idea de un post que se publicó en torno a herramientas de desarrollo para SharePoint 2007, la idea de este post y siguientes es ir creando una referencia a herramientas de desarrollo útiles para SharePoint 2010…espero que los lectores de este blog me ayuden en dicha labor. A continuación os dejo las que he recopilado para esta primera entrada:

Herramienta

Enlace de descarga / referencia

Using Visual Studio for SharePoint Development

http://msdn.microsoft.com/en-us/library/ee539321.aspx

Using SharePoint Designer for SharePoint Development

http://msdn.microsoft.com/en-us/library/ff458496.aspx

Debugging and Logging Capabilities in SharePoint 2010

http://msdn.microsoft.com/en-us/library/gg512103.aspx

SharePoint Developer Center

http://msdn.microsoft.com/en-us/sharepoint

SharePoint Log Reader

http://sharepointlogreader.codeplex.com/

ULS Viewer

http://archive.msdn.microsoft.com/ULSViewer

SharePoint ULS Log Viewer

http://ulsviewer.codeplex.com/

U2U CAML Builder

http://www.u2u.be/res/tools/camlquerybuilder.aspx

SharePoint Manager 2010

http://spm.codeplex.com/

.NET Reflector

http://www.reflector.net/

Stramit CAML Viewer

http://spcamlviewer.codeplex.com/

SharePoint Designer 2010

http://www.microsoft.com/download/en/details.aspx?id=16573

CKS for SharePoint 2010 Development

http://cksdev.codeplex.com/

CAML.NET Intelisense for Visual Studio 2010

http://visualstudiogallery.msdn.microsoft.com/15055544-fda0-42db-a603-6dc32ed26fde

Virtual Box

https://www.virtualbox.org/

CloudShare

http://www.cloudshare.com/

Fiddler

http://www.fiddler2.com/fiddler2/

Publicado 16/10/2011 9:25 por Juan Carlos González Martín | 4 comment(s)

Más artículos Página siguiente >