De un blogger MUY agradecido

Son casi las 9 de la noche y ya me iba del trabajo a casa cuando he recibido este correo:


Carlos,


I just wanted to take a moment (as others have) and thank you for the generous work you do, providing SharePoint solutions to the community.
Your hard work is shared and used by many; there are not a lot of people in this world willing to sacrifice their own time for others.


Thanks again,


Bill Burke 


No es el primero (y espero que no sea el último), pero me ha emocionado especialmente. Hay días más duros que otros y mensajes como este realmente te EMPUJAN ha seguir haciendo las cosas que haces.


Gracias a ti Bill y a todos.

MOSS 2007 Catalogo de datos empresariales BDC (1)

Una de las partes donde más ha cojeado SharePoint ha sido en la integración del portal o de los sitios de trabajo con otros sistemas como ERPs ó BBDD de la empresa.

En SharePoint v2 y en WSS2 disponíamos del DataViewer WebPart para incorporar datos que provenían de sistemas externos, si queríamos hacer cualquier otra cosa debíamos programarla y cosas lógicas como poder utilizar el sistema de búsqueda de SharePoint para localizar esos datos eran una misión imposible.

Para paliar todos estos escollos, MOSS 2007 nos ofrece el Business Data Catalog (BDC) ó Catálogo de datos empresariales.

MOSS 2007 nos ofrece una manera sencilla de incorporar esos datos y una API completa para poder programar interfaces de manera sencilla.

Para poder incorporar estos datos hay que realizar un interface por medio de un archivo XML que contendrá la definición de la conexión y las entidades con las que deseamos trabajar. Este archivo se ha de incorporar desde la administración centralizada para que este disponible en nuestro sistema.




El esquema de este documento se encuentra en (C:Archivos de programaMicrosoft Office Servers12.0Binbdcmetadata.xsd)

La estructura de dicho archivo es la siguiente :

LOBSystem (Line of Business System) – Define el catálogo de datos empresariales
<LobSystem xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance«
xsi:schemaLocationhttp://schemas.microsoft.com/office/2006/03/BusinessDataCatalog%20BDCMetadata.xsd«
Type=»Database»
Version=»1.0.0.0″
Name=»LOB_NorthWind»
xmlns
=»http://schemas.microsoft.com/office/2006/03/BusinessDataCatalog»>
LOBSystemInstance – Define la conexión con la BBDD
<LobSystemInstances>
<LobSystemInstance Name=»LOB_NorthWind»>
<Properties>
<Property Name=»DatabaseAccessProvider»
Type
=»Microsoft.Office.Server.ApplicationRegistry.SystemSpecific.Db.DbAccessProvider»>SqlServer</Property>
<Property Name=»RdbConnection Data Source» Type=»System.String»>SRVSQL</Property>
<Property Name=»RdbConnection Initial Catalog» Type=»System.String»>Northwind</Property>
<Property Name=»RdbConnection Integrated Security» Type=»System.String»>SSPI</Property>
<Property Name=»RdbConnection Pooling» Type=»System.String»>false</Property>
<Property Name=»AuthenticationMode»
Type
=»Microsoft.Office.Server.ApplicationRegistry.SystemSpecific.Db.DbAuthenticationMode»>PassThrough</Property>
</Properties>
</LobSystemInstance>
</LobSystemInstances>

Podemos establecer conexiones con Oracle, SAP, Siebel, ó a través de Servicios WEB


Entity – Define las distintas entidades de datos de este LOB. Son los conjuntos de datos de la conexión de datos, también aquí definiremos lo métodos y los filtros con los que recuperaremos la información.

<Entities>
<Entity EstimatedInstanceCount=»10000″ NameClientes«>
<Identifiers>
<Identifier TypeName=»System.String» Name=»CustomerID» />
</Identifiers>
<Methods>
<Method NameClientes«>
<Properties>
<Property Name=»RdbCommandType» Type=»System.Data.CommandType»>Text</Property>
<Property Name=»RdbCommandText» Type=»System.String»>
SELECT CustomerID, CompanyName, ContactName, ContactTitle, Address,
                            City, Region, PostalCode, Country, Phone, Fax
FROM dbo.Customers
WHERE CustomerID
LIKE @CustomerID
</Property>
</Properties>
<FilterDescriptors>
<FilterDescriptor Type=»ExactMatch» Name=»CustomerID» />
</FilterDescriptors>
<Parameters>
<Parameter Direction=»In» Name=»@CustomerID»>
<TypeDescriptor TypeName=»System.String» IdentifierName=»CustomerID» AssociatedFilter=»CustomerID» Name=»CustomerID»>
<DefaultValues>
<DefaultValue MethodInstanceNameClientesFinder« Type=»System.String»>%</DefaultValue>
<DefaultValue MethodInstanceNameClientesSpecificFinder« Type=»System.String»>%</DefaultValue>
</DefaultValues>
</TypeDescriptor>
</Parameter>
<Parameter Direction=»Return» NameCustomerss«>
<TypeDescriptor TypeName=»System.Data.IDataReader» IsCollection=»true» NameCustomersDataReader«>
<TypeDescriptors>
<TypeDescriptor TypeName=»System.Data.IDataRecord» Name=»CustomersDataRecord»>
<TypeDescriptors>
<TypeDescriptor TypeName=»System.String» IdentifierName=»CustomerID» Name=»CustomerID» />
<TypeDescriptor TypeName=»System.String» Name=»CompanyName» />
<TypeDescriptor TypeName=»System.String» Name=»ContactName» />
<TypeDescriptor TypeName=»System.String» Name=»ContactTitle» />
<TypeDescriptor TypeName=»System.String» Name=»Address» />
<TypeDescriptor TypeName=»System.String» Name=»City» />
<TypeDescriptor TypeName=»System.String» Name=»Region» />
<TypeDescriptor TypeName=»System.String» Name=»PostalCode» />
<TypeDescriptor TypeName=»System.String» Name=»Country» />
<TypeDescriptor TypeName=»System.String» Name=»Phone» />
<TypeDescriptor TypeName=»System.String» Name=»Fax» />
</TypeDescriptors>
</TypeDescriptor>
</TypeDescriptors>
</TypeDescriptor>
</Parameter>
</Parameters>
<MethodInstances>
<MethodInstance Type=»Finder»
ReturnParameterName
Customerss«
ReturnTypeDescriptorName
CustomersDataReader«
ReturnTypeDescriptorLevel
=»0″
Name
ClientesFinder«>
</MethodInstance>
<MethodInstance Type=»SpecificFinder»
ReturnParameterName
Customerss«
ReturnTypeDescriptorName
CustomersDataReader«
ReturnTypeDescriptorLevel
=»0″
Name
ClientesSpecificFinder«>
</MethodInstance>
</MethodInstances>
</Method>
</Methods>
</Entity>
</Entities>

A priori puede parecer un poco complicado pero no lo es. Además Todd Baginski ha creado un generador que hará las delicias de más de uno, el proyecto esta en CodePlex, pero la última versión la tiene accesible desde aquí.

WSS3 – Tipos de Contenido (Content Types) (5)

El panel de información del documento, también es una nueva característica de MOSS 2007 y WSS3.


Consiste en mostrar dentro del documento un panel con los datos correspondientes al tipo de contenido que estamos editando. Esto en versiones anteriores, nos aparecía en el momento en que íbamos a guardar el documento.



Ahora podemos ver un panel de información (que además podemos personalizar usando infopath)


Si alguno de los metadatos de nuestro tipo de contenido es de cumplimiento obligatorio, el documento no se podrá guardar.




Por último, si tenemos distintos tipos de contenido dentro de una biblioteca de documentos y cada uno de ellos tiene distintos metadatos asociados cuando realicemos una carga de documentos SharePoint, nos preguntará que tipo de documento es el que estamos cargando y en función del tipo de documento deberemos rellenar unos metadatos u otros.


WSS3 y MOSS 2007 Beta 2 TR – Software Development Kit

Con el lanzamiento de la Beta 2 TR, Microsoft ha actualizado los SDK para WSS3 y MOSS 2007



Esta documentación está disponible a traves de MSDN


WSS3 – Tipos de Contenido (Content Types) (4)

Para probar los tipos de contenido, podemos crear una lista personalizada, llamémosla “Proyectos” y renombremos el campo “Title” por “Proyecto”. Esta puede ser una lista en la cual figuren todos nuestros proyectos.


Supongamos que para cada proyecto tenemos tres tipos de documentos, el documento de especificaciones, el de presupuesto y el de contrato.


Podemos crear tres tipos de contenido, los tres se heredarán del tipo de contenido documento. También podemos crear primero un tipo llamado “Documento Base” y después heredar desde este los otros tipos.


Conviene hacer esto siempre que encontremos un denominador común en nuestros tipos de contenidos de este modo luego será mucho más fácil mantener nuestro sistema.



Nuestro tipo de contenido “Documento Base”, obviamente debería tener un campo que nos indique a que proyecto hace referencia.


Cuando creamos nuestro tipo de contenido “Documento Base”, heredado de “Documento”, automáticamente nos trae dos columnas “File” y “Title”. Ahora podemos añadir nuestra columna de sitio, con una referencia a los proyectos.


Crearemos una nueva columna de Sitio, llamada “Proyecto”






Una vez creada la columna de sitio, formará parte de nuestro tipo de contenido. Ajustamos las propiedades de las columnas, para que no se muestre el título y el “Proyecto” sea de obligatorio cumplimiento.




Con esto tenemos creado nuestro tipo de contenido “Documento Base”.


Bien, por el momento hemos creado un tipo básico de contenido que no es gran cosa pero ahora haciendo uso de las jerarquías veremos como esto se convierte en una poderosa herramienta.


Lo siguiente sería crear el tipo de contenido para el “Documento de Especificaciones” ahora lo que haremos será heredar del “Documento Base” con lo que tendremos una copia de el “Documento Base”. Para completar este tipo de contenido podemos añadir un nuevo campo que indicará si el documento es un borrador o una copia final.


Por último para completar este tipo de contenido, le asignaremos una plantilla. La plantilla del “Documento de Especificaciones”




Para el resto de documentos, crearíamos los tipos de contenido igual que hemos hecho con el “Documento de Especificaciones”. Si necesitamos algún nuevo metadato, lo podemos ir añadiendo en función de nuestras necesidades y si este metadato es común a todos los tipos de contenido que estamos creando bastará con añadirlo al “Documento Base”



Ya solo nos queda usar los tipos de contenido que hemos creado. Obviamente se usarán en una biblioteca de documentos. De modo que ahora lo primero que debemos hacer en la biblioteca de documentos en donde usaremos nuestros tipos de contenido es habilitar estos.



Una vez habilitados, los tipos de contenido, aparecerá una nueva sección en las propiedades de nuestra biblioteca de documentos donde podremos añadir los tipos de contenido. Por defecto aparece el tipo “Documento”, que podéis eliminar si no queréis usar un documento que no sea uno de los vuestros.


También se puede cambiar el orden en el que aparecen y el documento por defecto.



Por último al hacer hacer click en “Nuevo”  en nuestra biblioteca de documentación


Office 2007 Beta 2 Technical Refresh

Disponible para descargar desde hoy mismo desde :



A diferencia de otros TR os puedo decir que es una actualización que se instala sobre la Beta2, en la parte que me toca SharePoint os puedo adelantar que no es un proceso sencillo, muchos de los MVPs de SharePoint, hemos pasado las ultimas semanas tratando de instalarla y os aseguro que no ha sido un camino facil.




Installing Beta 2 Technical Refresh (B2TR) – What you need to know before you double click update.exe.


Guia de instalación de la Beta 2 Technical Refresh


Después de muchos, muchos intentos de instalación este es el camino más rápido para probar una instalación limpia de MOSS 2007.


1.- Windows 2003 Server + IIS + .Net  Framework 2.0 (registrado y activado)
2.- Instalar Windows Workflow Foundation 2.1
3.- Instalar MOSS 2007 (es) Sin ejecutar el asistente de configuración
4.- Desinstalar Windows Workflow Foundation 2.1
5.- Instalar .Net Framework 3.0
6.- Instalar WSS 2007 Technical Refresh (es)
7.- Instalar MOSS 2007 Technical Refresh (es)
8.- Ejecutar el asistente de configuración


 

WSS3 – Tipos de Contenido (Content Types) (3)

Anteriormente he hablado de los tipos de contenido y las columnas de sitio, personalmente mi manera de ver estos dos elementos es la siguiente:


Las columnas del sitio que debemos verlas como el glosario de términos con los cuales trabajamos. Y los tipos de contenido son agrupaciones y jerarquías de dichos términos. Supongo que os sonará la definición de “conocimiento” como el conjunto organizado de datos e información destinados a resolver un determinado problema.


Cada tipo de contenido se puede personalizar, con las columnas del sitio que queramos y con una serie de propiedades.



Document Information Panel settings – (Solo esta disponible para los tipos de contenido Document Content Types Page Layout Content Types y Publishing Content Types)


Dentro de las propiedades avanzadas (Advanced settings) podremos asignar a los tipos de contenido Document, Page y Content una plantilla desde la cual se creará ese tipo de contenido. Gracias a esto podremos asignar distintas plantillas a una biblioteca de documentos, lo veremos luego.



Para estos tipos también podremos personalizar el panel de información que se muestra dentro de las aplicaciones Office 2007.



También podemos aplicar un workflow para un determinado tipo de contenido, así como la política de gestión de este contenido (el típico disclaimer, las etiquetas que se han de imprimir cuando se imprima el documento, auditar ciertas acciones, fijar una fecha de caducidad del contenido y asignar un código de barras)  o las conversiones de documentos.

WSS3 – Tipos de Contenido (Content Types) (2)

Antes de continuar con los tipos de contenido vamos a ver otra importante mejora de WSS3 que tiene mucho que ver con los tipos de contenido.


Site Columns  (Columnas del sitio)


Las columnas del sitio, son columnas (campos) que podemos definir a nivel global (al igual que los tipos de contenido) para poder reutilizarlos después donde nos haga falta.


Las columnas del sitio, al igual que los tipos de contenido son actualizables, es decir que si tenemos una lista, que usa una columna que forma parte de las columnas del sitio, y actualizamos la definición de dicha columna, la lista se alterará de acuerdo a la nueva especificación.


Esto es un gran avance con respecto a WSS2 ya que en este no podíamos actualizar la definición de las listas de manera automática y había que hacer esto de una en una.


También, gracias a las columnas del sitio podemos recuperar datos de listas que no se encuentran sitios superiores, por ejemplo podemos tener una lista maestra de proyectos en nuestro nivel superior, y usar el contenido de esa lista en los subsitios.


¿Cuál es la relación entre las Columnas del Sitio y los Tipos de Contenido?


Los tipos de contenido agrupan columnas del sitio.


Tipos de Contenido


Existen distintos grupos de tipos de contenido, dentro de cada uno se encuentran los tipos básicos que incluye SharePoint.


Cada uno de los tipos que creemos, ha de heredarse de uno de estos o bien de uno que nosotros hayamos creado con anterioridad.


Los grupos con sus elementos básicos son:


 Bussiness Intelligence (moss 2007)
  Dashboard Page
  Indicator using data in Excel workbook
  Indicator using data in SharePoint list
  Indicator using data in SQL Server 2005 Analysis Services
  Indicator using manually entered information
  Report


 Document Content Types (moss 2007 & wss3)
  Basic Page
  Document
  Dublin Core Columns
  Form
  Link to document
  Master page
  Picture
  Web Part Page
  


 Folder Content Types (moss 2007 & wss3)
  Disscusion
  Folder
  
 List Content Types (moss 2007 & wss3)
  Announcement
  Contact
  Event
  Far East Contact
  Issue
  Item
  Link
  Message
  Task  


 Page Layout Content Types (moss 2007)
  Article page
  Redirect page
  Welcome page


 Publishing Content Types (moss 2007)
  Page
  Page Layout
  Publishing Master Page


 Special Content Types (moss 2007 & wss3)
  Unknown document type


Algunos de estos tipos solo están disponibles en MOSS 2007.


A priori puede parecer complicado pero no lo es, si creamos un tipo de contenido nuevo heredado de “List Content Types” -> “Contacts” lo que obtenemos es una copia de la definición de la lista de contactos. A partir de ese punto podemos personalizarla según nuestras necesidades.

WSS3 – Tipos de Contenido (Content Types) (1)

Una de las características importantes de WSS2 fueron los metadatos, en cada biblioteca de documentos podíamos definir una serie metadatos para poder estructurar nuestro contenido. Más tarde podíamos usar esos metadatos para recuperar información.



WSS3 potencia estos metadatos con lo que ha dado en llamar Content Types (Tipos de contenido).


¿Qué son los tipos de contenido?

Los tipos de contenido siguen siendo metadatos, es decir, datos estructurados que nos ayudan a identificar otros datos.


¿Qué diferencia existe entonces entre los metadatos y los tipos de contenido?

(Desvinculados) En primer lugar y la más importante, es que estos no están vinculados directamente con el lugar donde se almacenan los datos. Por ejemplo ahora podremos tener una biblioteca de documentos que almacene varios tipos de contenido, de manera que cuando añadimos un documento especificaremos de qué tipo de contenido se trata y en función de ese tipo completaremos una serie de metadatos u otra.

Debido a esto, los tipos de contenidos se definen para toda una colección de sitios, y podrán ser usados en cada uno de ellos así como en cada uno de los elementos que lo forman (listas, bibliotecas de documentos, sitios, workflows etc..)



(Jerárquicos) Los tipos de contenido son jerárquicos, un tipo de contenido puede estar basado en otro tipo de contenido, heredando todas las características del tipo padre.
Cundo damos de alta un nuevo tipo de contenido debemos especificar de que tipo heredaremos nuestro tipo de contenido.



(Actualizables) Otra gran diferencia con los metadatos es que los tipos de contenido son actualizables. Si variamos las especificaciones de un tipo de contenido, este cambio se propagará en todos aquellos elementos donde este se este usando.


Otras características de los tipos de contenido es la posibilidad de asignarles Workflows, Seguridad,  el documento plantilla que se usará para introducirlos o que datos formarán parte del panel de información que Office 2007 muestra para completar información



 

Los Eventos en WSS3

Otra de las características que se ha mejorado sustancialmente en WSS3 son los eventos, ahora podemos asociarlos a cualquier tipo de lista, sitio o un item en concreto, el SDK nos ofrece un tipo de receptor de eventos para cada uno de ellos, por el momento (y como estamos hablando de una del SDK) las clases son Microsoft.SharePoint.SPItemEventReceiver, Microsoft.SharePoint.SPListEventReceiver  y Microsoft.SharePoint.SPWebEventReceiver


Los eventos tienen dos formas, la que esta en pasado que se llevará acabo cuando el evento ya se ha producido, es decir después  y la continua que se llevará acabo antes de que el evento ocurra. Con todo esto, disponemos de los siguientes eventos:


 




















































































SPItemEventReceiver SPListEventReceiver SPWebEventReceiver
ItemAdded FieldAdded SiteDeleted
ItemAdding FieldAdding SiteDeleting
ItemAttachmentAdded FieldDeleted WebDeleted
ItemAttachmentAdding FieldDeleting WebDeleting
ItemAttachmentDeleted FieldUpdated WebMoved
ItemAttachmentDeleting FieldUpdating WebMoving
ItemCheckedIn

 


 

ItemCheckedOut

 


 

ItemCheckingIn

 


 

ItemCheckingOut

 


 

ItemDeleted

 


 

ItemDeleting

 


 

ItemFileConverted

 


 

ItemFileMoved

 


 

ItemFileMoving

 


 

ItemUncheckedOut

 


 

ItemUncheckingOut

 


 

ItemUpdated

 


 

ItemUpdating

 


 


 


De manera que si deseamos realizar eventos para los elementos de una lista, usaremos la clase base SPItemEventReceiver e iremos sobrescribiendo aquellos métodos que deseemos controlar.

public class MiEventHandler : SPItemEventReceiver
{ …. }

Por ejemplo si tenemos una lista que llamaremos demo y queremos que al añadir un elemento nos indique en un campo datos que es un elemento nuevo, y que siempre que se modifique un elemento nuevo en dicha lista el campo nuevo pase a contener modificado, y por último que no se pueda eliminar ningún elemento de dicha lista sin que previamente se haya modificado.


Deberemos sobrescribir, ItemAdded, ya que lo que pretendemos es modificar el contenido de un campo llamado datos una vez añadido un elemento para que tome el valor «Nuevo».

public override void ItemAdded(SPItemEventProperties properties)
{
SPListItem listItem = properties.ListItem;

listItem[«Datos»] = «Nuevo « + properties.EventType.ToString();

DisableEventFiring();
listItem.Update();
EnableEventFiring();
}


Cada uno de los eventos recibe información sobre el evento en por medio de SPItemEventProperties, como el tipo de evento (lo he añadido también en nuestro campo Datos, para que se vea claramente que acción ha realizado cada uno de los eventos, usando properties.EventType.ToString() ), el usuario que lo esta llevando acabo, el item de la lista que se esta tratando etc…. Es importante destacar en SPItemEventProperties, que a través de el recibimos información y también devolvemos información.


Usando  SPItemEventProperties.BeforePropertiesSPItemEventProperties.AfterProperties, podemos obtener información sobre como estaba la lista antes y después de que se produzca el evento, y a través de la SPItemEventProperties.Cancel y SPItemEventProperties.Error podemos cancelar un evento y devolver un mensaje de error.


Durante la actualización del Item y dado que vamos a sobrescribir también ItemUpdated momentáneamente deshabilitaremos los eventos, de no hacerlo así al llamar a listItem.Update se lanzaría el evento ItemUpdated.


Como he dicho antes, ahora nos interesa controlar que cuando se edite por primera vez un elemento nuevo el campo de datos contenga «Modificado», por lo que ahora sobrescribiremos ItemUpdated, para que se vea quien ha realizado cada una de las acciones he añadido properties.EventType.ToString() .

public override void ItemUpdated(SPItemEventProperties properties)
{
SPListItem listItem = properties.ListItem;

if (listItem[«Datos»].ToString().Contains(«Nuevo»))
{
listItem[«Datos»] = «Modificado « + properties.EventType.ToString(); ;
listItem.Update();
}


Por último sobrescribiremos ItemDeleting, esta acción la queremos controlar antes de que se produzca el evento, ya que así podremos denegar el borrado.

public override void ItemDeleting(SPItemEventProperties properties)
{
SPListItem listItem = properties.ListItem;

if (listItem[«Datos»].ToString().Contains(«Nuevo»))
{
properties.Cancel = true;
properties.ErrorMessage = «No se puede eliminar un elemento Nuevo»;
}
}


Finalmente deberemos compilar nuestra biblioteca de clases, firmarla e instalarla en el GAC.


Para asociar nuestra biblioteca de eventos a una lista en particular, podemos escribir una pequeña aplicación de consola para realizar el trabajo o bien usar algo como este Event Handler Explorer de Patrick Tisseghem

using System;
using Microsoft.SharePoint;

namespace ConsoleTools
{
class Program
{
static void Main(string[] args)
{
SPSite site = new SPSite(«http://spsbeta/SiteDirectory/test»);
SPWeb web = site.OpenWeb();
SPList list = web.Lists[«Demo»];

string ensamblado = «MiWebPart, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d196fc71b3d34a48»;
string clase = «MiWebPart.MiEventHandler»;

list.EventReceivers.Add(SPEventReceiverType.ItemAdded, ensamblado, clase);
list.EventReceivers.Add(SPEventReceiverType.ItemUpdated, ensamblado, clase);
list.EventReceivers.Add(SPEventReceiverType.ItemDeleting, ensamblado, clase);

}
}
}


Básicamente abre un sitio web en busca de una lista y con la información del ensamblado vamos indicando que tipo de eventos son los que controlará nuestra biblioteca.


Creo que el cambio y las mejoras en los eventos de WSS3 tienen un potencial increíble para automatizar nuestros sitios.