SharePoint Latin Rotating Header Image

Windows SharePoint Services 3.0

Programando con Listas en Windows SharePoint Services 3.0

Aquí un entrenamiento que di hace muchos años para una empresa en la que trabajé como líder de practica de colaboración. Básicamente preparé esta presentación para mostrar a programadores como manejar listas y elementos de forma programática a fin de introducirlos al mundo de la programación SharePoint.


Durante una revisión a un respaldo me encontré con los archivos fuente de este WebCast y decidí compilarlo como video para subirlo a mi canal de Youtube. Si por alguna razón sigues dando soporte a plataforma SharePoint 2007 (MOSS o WSS 3.0) en temas de programación este video sin duda es una referencia que te permitirá entender los fundamentos de programación de listas en SharePoint.


Además, creo que los temas aquí mencionados también aplican para SharePoint 2010 J



Usando los controles de SharePoint en WebParts

Sin duda, con el poder viene la responsabilidad. En pasados días publiqué un post acerca de cómo utilizar los controles de ASP.NET y toda su experiencia gloria dentro de WebParts de SharePoint. Sin embargo, al utilizar esta estrategia un conjunto de consideraciones subsecuentes deberán ser contempladas como hacer uso de los mismos controles SharePoint dentro de estos WebParts.


En ese sentido, debido a que sin problema alguno puedo utilizar el GridView y/o cualquier control ASP.NET al principio suena atractiva la posibilidad pero como siempre la realidad se asoma y nos muestra al que un día fue novedoso control Calendar de ASP.NET y con todo el debido respeto, hoy no es la mejor opción para la captura de una fecha dentro de una forma en SharePoint, al menos la mejor opción es usar el mismo control que se usa en SharePoint, ¿estás de acuerdo?


Vamos a nuestro Web User Control y registramos los controles web de SharePoint. Estos son los controles mejorados que SharePoint internamente utiliza en su capa de presentación.


image


Después dentro de nuestro código Markup agregamos el control SharePoint que requerimos:


image


Lo interesante es que tenemos una gama de controles de SharePoint disponibles.


image


A continuación dentro del código hacemos referencia al control de SharePoint para poder adjuntar algún evento o leer su valor.


image


Y el resultado es:


image


Estos controles cuentan con validaciones, propiedades y eventos que podemos utilizar a nuestro favor. Créditos a Luis Edmundo Teos por el reto y escenario.


Suerte!

Programación ASP.NET en WebParts de SharePoint

Si eres un de desarrollador ASP.NET que se está iniciando en desarrollo SharePoint este ejemplo puede ser de utilidad. Básicamente, usaremos un enfoque de desarrollo de WebParts basado en el uso de Web User Controls de ASP.NET 2.0.

Antes que nada utilizaremos las siguientes herramientas:

Dentro de nuestro servidor de desarrollo SharePoint cargamos Visual Studio 2008 y elegimos la creación de un proyecto SharePoint en blanco, este proyecto lo nombraremos ASPNETWebPart.

clip_image002

Especificaremos que el nivel de confianza de esta solución SharePoint sea Full Trust y la razón es que usaremos un método Page.LoadControl que requiere de permisos elevados para ejecutarse, me parece que la razón es porque este método lee de la ruta de archivos SharePoint “12 hive” y para ello requiere que el proceso w3wpg.exe solicite los permisos necesarios.

clip_image004

Usando la solución generada por Visual Studio 2008 dentro del Solution Explorer agregamos un nuevo Empty Web Site de ASP.NET llamado ASPNETWebPArtsWebSite ubicándolo en la misma carpeta creada por nuestro proyecto anterior.

clip_image006

Dentro de nuestro proyecto ASPNETWebPartWebSite agregamos un Web User Control llamado ASPNETWebUserControl y es muy importante que no deseleccionemos el cuadro de verificación Place Code in separate file.

clip_image008

Esto nos crea un simple archivo con extensión .ascx dentro de nuestro proyecto ASP.NET. A estas alturas podremos realizar cualquier funcionalidad ASP.NET. Solo hay que asegurarnos de no generar dependencias a otras carpetas como App_Code, tratemos de generar todo el código y funcionalidad sobre el Web User Control. En mi caso usare las características de vinculación de controles de ASP.NET para crear el más humilde de los GridView de ASP.NET. Podemos crear una página Defaullt.aspx para probar el funcionamiento del mismo. A continuación agregare un cuadro de texto , un botón y un label.

clip_image010

El resultado es un código Markup que podría tener sin duda código C#. En la sección de Script runat=”Server” estarían los eventos disparados por los controles de nuestro Web User Control. Solo que para propósitos de este ejemplo quiero hacer que los eventos sean disparados desde un WebPart de SharePoint y no necesariamente desde aquí.

A continuación en nuestro proyecto SharePoint agregamos un elemento de tipo Template, el cual nos creara un archivo dentro de la ruta interna de archivos de SharePoint o más conocida como 12 hive “C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\”.

clip_image012

Eliminamos el archivo generado TemplateFile.txt y agregamos la carpeta CONTROLTEMPLATES y dentro la carpeta ASPNETWebParts. Esto permite incluir en nuesdttro paquete de deployment generado por nuestro proyecto SharePoint una nueva carpeta que será aprovisionada de forma confiable en la ruta 12 hive de cada Web Front End de la granja SharePoint. Agregara una nueva carpeta llamada ASPNETWebParts. Dentro de esta carpeta agregaremos como elemento existente nuestro archivo .ascx. El resultado es algo asi:

clip_image014

Ya casi terminamos, a continuación agregamos el código de un WebPart de SharePoint que nos permitirá cargar en tiempo de ejecución el .ascx recién desarrollado. Dentro de nuestro proyecto ASPNETWebPart damos clic derecho y agregamos un nuevo elemento de tipo Web Part bajo el nombre ASPNETWebPart. En realidad puede ser cualquier nombre.

clip_image016

Abrimos el código de nuestro WebPart y agregaremos lo siguiente:

  1. Una variable miembro de tipo UserControl, esta se utilizara como un placeholder de todo el ASPNETWebUserControl.ascx.
  2. Sobre escribimos el método Render para escribir en el flujo de salida de nuestro WebPart el contenido del WebUserControl.
  3. Múltiples variables miembro que representan cada uno de los controles que existen en nuestro archivo ASPNETWebUserControl.ascx
  4. En el evento CreateChaldControls hacemos una instancia de UserControl mediante Page.LoadControl y de cada uno de los controles;

Básicamente podremos tener el control de la funcionalidad desde el WebPart y esto facilita el hacer uso del modelo de objetos de SharePoint para leer datos de otras listas o hacer querys que podamos usar para después presentarlos en el Web User Control.

using System;

using System.Runtime.InteropServices;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Xml.Serialization;

using Microsoft.SharePoint;

using Microsoft.SharePoint.WebControls;

using Microsoft.SharePoint.WebPartPages;

namespace ASPNETWebPart

{

[Guid("7625d718-fb33-4bbc-b05f-2f1ff0dd4a88")]

public class ASPNETWebPart : System.Web.UI.WebControls.WebParts.WebPart

{

public ASPNETWebPart()

{

this.ExportMode = WebPartExportMode.All;

}

protected override void Render(HtmlTextWriter writer)

{

this.ascxControl.RenderControl(writer);

}

UserControl ascxControl;

Button button1;

TextBox textbox1;

Label label1;

GridView gridView1;

protected override void CreateChildControls()

{

base.CreateChildControls();

ascxControl = (UserControl)Page.LoadControl(@"/_controltemplates/ASPNETWebParts/ASPNETWebUserControl.ascx");

button1 = (Button)this.ascxControl.FindControl("Button1");

textbox1 = (TextBox)this.ascxControl.FindControl("TextBox1");

label1 = (Label)this.ascxControl.FindControl("Label1");

gridView1 = (GridView)this.ascxControl.FindControl("GridView1");

button1.Click += new EventHandler(button1_Click);

this.Controls.Add(ascxControl);

}

void button1_Click(object sender, EventArgs e)

{

label1.Text = textbox1.Text;

}

}

}

El resultado:

clip_image018

Como validar campos en formularios de listas personalizadas de SharePoint con SharePoint Designer

Lo único que puedo decir es que aquellos pequeños y finos detalles dejan un sabor mucho más agradable a la experiencia.

Durante un pasado servicio de soporte se solicitó un requerimiento de validar que el campo fecha de una lista personalizada, no permitiera ingresar fechas mayores o iguales al día de hoy. Sin duda, de primera mano y como todo un programador piensas en construir un Custom Field que contenga la funcionalidad solicitada, sin embargo, todas las implicaciones y costo de desarrollar, probar, implementar y mantener una funcionalidad como tal no se justifica como para esta necesidad solicitada y el sentido de urgencia.

El folclórico y temperamental SharePoint Desginer 2007 a.k.a “SPD” hace su aparición como una alternativa para realizar la validación solicitada.

Básicamente la solución será:

  1. Copiar y pegar la página NewForm.aspx de la lista en cuestión con el nombre de NewFormEnhancement.aspx
  2. Abrir la página y poner invisible el primer WebPart
  3. Agregar un Custom List Form de tipo New para la lista en cuestión
  4. Agregar validadores a field donde requerimos la funcionalidad

1. Copiar y pegar la página NewForm.aspx de la lista en cuestión con el nombre de NewFormEnhanced.aspx image

  • Cargamos el sitio en cuestión usando SPD, asegúrate de firmarte al sitio en cuestión  con una cuenta que por lo menos el permiso de Site Collection owner.
  • Cuando cargas el sitio podrás ver en forma de árbol el contenido.
  • Expande la carpeta Lists y de los elementos mostrados expandes la lista que deseas personalizar. Observa que se tienen un conjunto de archivos .aspx, selecciona NewForm.aspx y da clic derecho, copia la página y ahí mismo pegas con el nombre de NewFormEnhancements.aspx

2. image Abrir la página y poner invisible el primer WebPart

  • Das doble clic sobre NewFormEnhanced.aspx. SPD carga la página para poder ser editada.
  • Da clic sobre el único WebPart en la página y da clic derecho para elegir la opción de WebPart Properties. WebPart Properties carga el panel de propiedades correspondiente.
  • Expande la sección de Layout y da clic sobre el cuadro de verificación Hidden. Esto hace que en la página en cuestión el WebPart pre determinado no este visible.

3. Agregar un Custom List Form de tipo New para la lista en cuestión

  • imageEn el código Markup de la página en cuestión buscamos el lugar donde se encuentra  </WebPartPages:
    ListFormWebPart>
    </ZoneTemplate>
    </WebPartPages:
    WebPartZone>
    y justo debajo posicionamos nuestro cursor.
  • Seleccionamos del menú Insert la opción SharePoint Controls y Custom List Form. Esto carga una ventana de dialogo que nos permite seleccionar el tipo de WebPart que deseamos insertar sobre nuestra página personalizada.
  • image Configuramos el tipo de forma de captura que será aprovisionado por esta ventana de dialogo. Básicamente elegimos la lista de la cual necesitamos una instancia del formulario de captura y muy importante es el tipo de formulario de captura que requerimos como la forma de nuevo elemento, forma de modificación de un elemento o forma de visualización de un elemento. Elegimos New Item form, damos clic en Ok y esto genera una nueva instancia de la forma de captura para nuevos elementos de la lista que elegimos. Esta forma de captura es aprovisionada en código Markup de tipo WebPartPages:DataFormWebPart el cual expone los fields que el formulario tiene y el layout HTML donde estos fields son ubicados en la forma, esto nos da grandes posibilidades de personalización visual.

4. Agregar validadores a field donde requerimos la funcionalidad

  • image Buscamos el field de tipo fecha que deseamos validar.
  • Nos aseguramos de modificar el tipo de control que se tiene configurado. Simplemente seleccionamos el control en cuestión y damos clic derecho sobre él, elegimos la opción de Show common control task cargando con ello una sección donde podemos elegir el tipo de control. Como podemos ver seguramente tenemos la opción de Form Field como Format As, damos clic sobre el cuadro de selección y elegimos Date Picker. Esto hace una especie de cambio en el control.
  • Damos clic derecho Properties sobre el control y buscamos la propiedad ID en mi caso fue “ff6_1”. Este ID es muy importante ya que con el podremos asociarlos a otros controles del lado servidor como TextBox, Validation Controls,. etc. Lo único importante que se debe de contemplar es que cuando utilizamos los controles de ASP.NET o nativos de SharePoint, estos hacen referencia al control no con el ID como tal, sino con el siguiente patrón “ID$IDTipoDeDato” en otras palabras “ff6_1$ ff6_1Date”.
  • Dentro del código Markup buscamos la terminación de la declaración del control Date Picker “</SharePoint:DateTimeControl>” y justo abajo pegamos el siguiente código:

<SharePoint:InputFormCustomValidator

ClientValidationFunction="IsValidDate"

ID="custvDueDate"

runat="server"

Display="Dynamic"

SetFocusOnError="false"

ControlToValidate="ff6_1$ff6_1Date"

BreakBefore="true"

BreakAfter="false"

ErrorMessage="Date must be grater than today" />

Como se puede observar, tenemos controles del lado servidor específicos de SharePoint. Estos controles heredan de los controles de validación de ASP.NET y agregan otro comportamiento adicional muy similar a los de ASP.NET pero especial para SharePoint. Mediante las directivas pre definidas en la página podemos acceder a ellos.  Karine Bosch explica aquí cada uno de estos controles y lo hace muy bien. Favor de ver este post antes de continuar.

En el caso de InputFormCustomValidator lo estamos usando para realizar una validación sobre el field Due Date. Recuerda que la regla es NO permitir la captura de fechas mayores o iguales al dia de hoy. El control de validación custom InputFormCustomValidator  nos permite asignar código compilado .NET para realizar la validación en cuestión, solo que bajo el contexto de ejecución de SharePoint se requeriría hacer algunas modificaciones en el web.config para permitir la compilación de la página, sin embargo, este control nos permite hacer lo mismo utilizando código del lado del cliente. Y justo ese es el escenario que pienso compartir aquí.

Básicamente estamos confiando en realizar la validación desde el navegador de internet utilizando Javascript. Como ven, la propiedad ClientValidationFunction apunta a una función Javascript “IsValidDate” encargada de realizar la validación personalizada y este código javascript deberá de estar referenciado o registrado en la página en cuestión y lo hacemos agregandolo dentro de un Content Place Holder especial. Cuando el usuario capture una fecha sobre el control, este dispara el uso de la función javascript para validar la información capturada, la funcion javascript recibe en sus argumentos el source y args, en otras palabras el objeto que lo dispara y algunos argumentos del objeto como el valor que contiene. Cuando args.IsValid es igual a true significa que la validacion es correcta y por lo tanto hace que el control InputFormCustomValidator no muestre el mensaje de error. Cuando es false, hace lo contrario.

Este código javascipt lo podemos agregar justo al inicio de la página después de la declaración de las directivas:

<asp:Content ContentPlaceHolderId="PlaceHolderAdditionalPageHead" runat="server">

<script language="javascript" type="text/javascript">

function IsValidDate(source, args)

{

var today = new Date(new Date().setHours(0,0,0,0));

var arrayDate = args.Value.split("/");

var controlDate = new Date(arrayDate[2], arrayDate[0]-1, arrayDate[1]);

args.IsValid =( today<controlDate);

}

</script>

</asp:Content>

Como podemos ver utilizamos un Content Place Holder que no propiamente estaba declarado dentro de la página y adentro agregamos el javascript de la función IsValidDate el cual recibe como argumento el dato que se desea validar. Con funcionalidad javascript se generan variables de tipo date para gestionar la comparación.

El resultado:

image

No olvides dar check in a la pagina para poder probarla. Para terminar, asegurate de especificar en las propiedades de la lista en cuestion tu nueva pagina como la pagina principal para agregar elementos en la lista. Con esto cuando un usuario de clic en New dentro de la lista, SharePoint carge la nueva pagina personalizada.

  • En SPD, das clic derecho sobre la lista en cuestion.
  • Seleccionas Properties.
  • Seleccionas la pestaña Supporting Files y en new item from buscas la nueva pagina creada.

image

Credito a Hector Mata por el codigo javascript, gracias!

Configurando acceso anónimo y restringido a una Extranet de SharePoint 2007 en 30 minutos

ahorrar_en_proveedores_articulo_portraitContinuando con el tema de la Intranet-Extranet configurada aquí, me di a la tarea de acércame al siguiente reto una vez que enfrentamos un escenario de extranet. Este reto consiste en ofrecer a los usuarios externos algún mecanismo de registro y de gestión de perfiles. En este video vemos como configurar el acceso anónimo en la zona de Extranet, vemos como utilizando SharePoint Designer 2007 podemos personalizar páginas que hagan uso de controles de servidor de ASP.NET 2.0 y de WebParts de SharePoint.


Adicional vemos como romper con la herencia de permisos para poder contar con porciones de contenido privadas y públicas. Las públicas, son páginas de registro y de inicio de sesión, las privadas son páginas restringidas que muestran mediante WebParts listas personalizadas configuradas especialmente.


Dicho lo anterior, esto permite ofrecer un mecanismo para restringir el acceso a ciertas listas y solo hasta que el usuario se registre, alguien con permisos elevados desde la Intranet otorgue el rol “Extranet” al usuario en cuestión (esto permite contar con un proceso de validación del usuario antes de darle acceso a cualquier contenido restringido) este podría acceder a subir la información requerida.


Adicional, vemos como configurar una lista personalizada de SharePoint para que la información que el usuario externo aporte sea visible solo para él y para cualquier usuario de la Intranet, permitiendo con esto aplicar algunas otras funcionalidades de SharePoint para colaboración o seguimiento interno por parte de empleados de la organización.


El ejemplo se basa en un escenario de extranet para proveedores donde estos pueden subir documentación e información de negocio que permita a la empresa iniciar con los trámites necesarios para darlo de alta como proveedor. Adicional, este ejemplo podría utilizarse como un mecanismo para concurso de RFPs o para recopilación de información provista por actores externos a la empresa pero que participan en la cadena de valor.


Espero sea de utilidad, está por demás decir que este es un ejemplo de tan solo 30 minutos que ilustra conceptos y aspectos tecnológicos que pudiesen acercarse a una solución.


 



 


Utilizar estos consejos es bajo tu propio riesgo, explora, aprende y comparte!.


HG

Intranet-extranet de SharePoint en 40 minutos

En las últimas semanas colegas programadores que no conocen SharePoint 2007 se acercan para preguntar y evaluar si SharePoint puede dar una solución aceptable para escenarios donde usuarios externos (fuera del directorio activo) a la organización colaboren con usuarios internos (dentro del directorio activo) en algún proceso de negocio relevante para la organización.


Afortunadamente SharePoint 2007 fue construido utilizando .NET Framework 2.0/3.0 y sobre ASP.NET 2.0 por lo tanto las características que cualquier programador ASP.NET 2.0 conoce prácticamente las tenemos disponibles en SharePoint 2007, aunque esto no necesariamente aplica para la experiencia de desarrollo Sad smile.


Dicho lo anterior, tuve un par de reuniones explicando como sí SharePoint 2007 podría habilitar el escenario mencionado, sin embargo, por más que lo explico y lo justifico, no hay mejor opción que demostrarlo. Es por eso que me di a la tarea de grabar un video de cómo configurar una Intranet que hace uso de directorio activo como su fuente de credenciales de usuario y Extranet que hace uso Membership y Role Providers de ASP.NET 2.0 para gestionar usuarios en bases de datos SQL utilizando las características de Form Base Authentication. En el proceso podran visualizar como la Herramienta Central de Administracion de SharePoint aprovisiona base de datos de contenido, web sites de IIS y application pool. Smile



NOTA: Es muy importante mencionar que ninguna intranet-extranet que se utilice empresarialmente en escenarios de producción quedara configurada en 40 minutos, hay aspectos de planeación, configuración y seguridad que se deben de contemplar muy seriamente.


Y para terminar un poquito de arquitectura basica sobre un escenario en cuestion:


  • SPDB: Database Server
  • SPAPP: SharePoint Application Server
  • SPWFE1: Web Front End en Zona Intranet
  • SPWFE2: Web Front End en Zona Extranet
  • AD: Directorio Activo
  • EX: Exchange
  • ISA: ISA Server o firewall fisico

image


Como se refiere en la imagen, tenemos servicios dos zonas, Intranet y DMZ. Intranet hace uso de los recursos de red internos de la organización como directorio activo o servidor de correo electrónico, entre otro. En la misma zona interna tenemos una Topologia Small Farm de SharePoint con un solo Web Front End que usuarios internos podran acceder mediante http://intranet.splatin.com. En la zona DMZ tenemos otro Web Front End unido a la granja filtrado por un firewall hacia adentro y hacia afuera. Puede ser firewall de software como el caso de ISA Server o de hardware. Podriamos pensar que el Web Front End de la zona DMZ tenga 2 tarjetas de red, una para trafico externo con IP publica y dominio como http://extranet.splatin.com, y otra tarjeta para trafico interno con IP privada o de la red local. Aqui tenemos otras alternativas de configuración mas sofisticadas que el area de infraestructura seguramente podra aprovisionar. Usuario con acceso a internet llega al Web Front End de la zona DMZ pasando por el firewall.


Para ti que eres programador ASP.NET y estas evaluando SharePoint espero sea de utilidad este breve ejemplo acercamiento de solución.


HG

Cuantos ingenieros se necesitan para cambiar una bombilla o crear sitios SharePoint

No es curioso, es un hecho que en el ambiente laboral relacionado con tecnologías de información y seguramente en muchos otros, nos encontramos con diversas personalidades, temperamentos y arquetipos colaborando día con día para resolver algún problema técnico o de negocio. Las personas tenemos toda una historia distinta, además de cualidades que en parte de forma consiente o inconsciente constituye la forma muy particular de ver y reaccionar ante vida, en algunos casos estas cualidades son las adecuadas para ciertos escenarios pero que en definitiva en otros no lo son.

Entonces la pregunta es, ¿cómo aprovechar lo que cada quien aporta para generar valor empresarial?, esa es una pregunta que especialistas en Management, Leadership y Coaching podrían responder sin ningún problema. Sin embargo, desde mi óptica por lo menos compartir constantemente una visión compartida con lineamientos claros es esencial para organizar y aprovechar lo que cada persona con su historia histeria y experiencia aporta.

En esta historia, el requerimiento es crear un conjunto finito de sitios con las siguientes características:

  • Cada sitio se basa en la plantilla de sitio de Trabajo en Equipo
  • Cada sitio no deberá tener herencia de permisos
  • Cada sitio deberá contar con 4 grupos “Owners, Visitors, Members, Permissions” bajo la nomenclatura “Sitio + Nombre de grupo
  • Cada sitio cuenta con usuarios específicos para cada grupo.

Lo que piensan los miembros del equipo de TI:

  • Miembro 1 – Vamos a lucirnos con la solución, hagamos un WSP con feature receiver a nivel sitio web para que cuando le den activar en las características del sitio, programáticamente los construya y configure.
  • Miembro 2 – ¿Hay urgencia por parte del cliente como para dedicar tiempo a construir y probar un WSP?, ¿se va a reutilizar la jerarquía en algún otro sitio en el futuro?, ¿conviene dejar archivos en el 12 hive y un ensamblado en el GAC con full trust assembly?, ¿vamos a implementar en DEV, QA, UAT y PROD el WSP? Yo digo que construyamos los sitios manualmente usando el UI de SharePoint.
  • Miembro 3 – Usemos scripts en un archivos *.bat que ejecute el comando stsadm.exe para crear los sitios y grupos, pasamos parámetros e nivel comando y creamos un solo archivo que cuente con todas las instrucciones necesarias.

Después los miembros dan inicio a los argumentos técnico-personales para defender su postura a capa y espada, como si fueran program managers de microsoft, correos electrónicos empiezan a fluir con preguntas que toman minutos leer y escribir de regreso para ser enviados de nuevo. El tiempo pasa, el tema sube de nivel, siguen estancados, el usuario pregunta por sus sitios y en eso Miembro 2 lo toma personal, sube de nivel su contestación y claudica ante su postura. Miembro 1 ratifica la postura de Miembro 2 con el afán de no afectar al equipo y Miembro 3 procede a ejecutar la postura del Miembro 2. Tiempo total transcurrido 2.5 horas.

Si lo analizamos, todos pierden. El espíritu del equipo se deteriora, definitivamente se ve mal y el usuario de plano esperando. Realmente cualquier postura es aceptable y totalmente factible, cada una con sus peculiaridades, estimaciones, esfuerzos y consecuencias.

Dicho esto, tengo 2 preguntas:

  1. ¿Cómo podríamos contextualizar las cosas para asegurar que antes de dar inicio a una solución construida por ingenieros, todos estén viendo hacia el mismo lugar? Esa es una respuesta que probablemente podamos encontrar aquí http://www.crecenegocios.com/los-objetivos-de-una-empresa/
  2. ¿Qué estrategia técnica conviene utilizar para un escenario donde el resultado se requiere de inmediato? A veces me pregunto si mi trabajo es preguntar, sin embargo haciendo un intento de posible respuesta, dejo algunos cuestionamientos respecto al escenario planteado y claro, su implementación.

Construyendo sitios de forma manual

Pros

  • Rápida ejecución usando UI de SharePoint
  • Cero dependencia a código, ensamblado o XMLs, todo queda en la base de datos usando los site definitions y templates propietarios de SharePoint que si están considerados para ser migrados y respaldados

Cons

  • No es repetible
  • Requiere de intervención manual para replicar en cada ambiente y por lo tanto hay margen de error

Implementación

Ubicados en el sitio en cuestión accedemos a Acciones de sitio, Configuración del sitio, Toda la configuración del sitio y al de final las galerías elegimos crear sitios o área de trabajo. Especificamos el nombre, url y los siguientes puntos:

Crear sitio Configurar grupos
image image

 

Construyendo sitios programáticamente

Pros

  • Total portabilidad a múltiples ambientes y sitios con mínimo esfuerzo de implementación
  • Aprovisionamiento y des aprovisionamiento flexible de la funcionalidad y dependencias

Cons

  • Crea una dependencia a un WSP, ensamblado en GAC y archivos en 12 hive
  • Requiere de construcción, pruebas, empaquetamiento y puesta en marcha en cada ambiente
  • Pasa a control de versiones y gestión

Implementación

En este caso vemos que utilizamos una colección especial de tipo diccionario para almacenar la URL y Nombre del sitio que deseamos crear. Existen varias formas de hacer lo mismo, en este caso recorremos la colección de plantillas SharePoint para poder elegir la que usaremos “Team Sites”. Recorremos la colección de nuestro diccionario y utilizamos la colección Webs para agregar un nuevo site pasando los argumento recolectados, lo mas importante destacar en este punto es que el ultimo argumento false indica que no se mantiene la herencia y a continuación ya dentro del sitio rompemos la herencia, posteriormente recorremos el arreglo que tiene el nombre de los grupos que estaremos construyendo programáticamente, ese código se los debo y si alguien quiere compartirlo adelante.

           uint        lcid_english = 1033;
            string      siteUrl = "http://portal.litwareinc.com";
            string[]    groupTypeNames = {"Owners","Members","Permissions","Visitors"};

            Dictionary<string, string> targetSites = new Dictionary<string, string>();
            targetSites.Add("demo1", "Sitio de demostracion 1");
            targetSites.Add("demo2", "Sitio de demostracion 2");
            targetSites.Add("demo3", "Sitio de demostracion 3");
                    
                using (SPSite site = new SPSite(siteUrl))
                {
                    SPWebTemplate siteTemplate = null;
                    SPWebTemplateCollection templateCollection = site.GetWebTemplates(lcid_english);
                    
                    foreach (SPWebTemplate template in templateCollection)
                    {
                        if (template.Title.Equals("Team Site"))
                        {
                            siteTemplate = template; 
                            break;
                        }
                    }

                    using (SPWeb web = site.OpenWeb())
                    {
                        foreach (KeyValuePair<string, string> siteInfo in targetSites)
                        {
                            using (SPWeb newWeb = web.Webs.Add(
siteInfo.Key, 
siteInfo.Value, 
string.Empty, 
lcid_english, siteTemplate, false, false))
                            {
                                newWeb.BreakRoleInheritance(false);
                                newWeb.Update();

                                foreach(string groupTypeName in groupTypeNames)
                                {
                                    string groupType = string.Format("{0} {1}",siteInfo.Value,groupTypeName);
                                    
                                    // aqui deberas crear el grupo y asignar los permisos         
                                }                                                                  
                            }                            
                        }
                    }                
                } 



Construyendo sitios con comandos stsadm.exe


Pros


  • Reutilización moderada e intervención manual para especificar sites, groups que se aprovisionaran por los comandos
  • Fácil de corregir y reaccionar ante cualquier error
  • La forma recomendada por Microsoft

Cons


  • Crea una dependencia al script que ejecuta los comandos de staadm.exe para la estructura solicitada
  • Pasa a control de versiones y gestión

Implementación


En esta alternativa utilizamos las sentencias del comando stsadm.exe ubicado en c:\program files\common files\microsoft shared\web server extensions\12\bin especificando mediante –o la opción que deseamos y mediante los parámetros especificamos lo que requerimos. Específicamente –unique describe que no queremos heredar los permisos. Subrayo en rojo la parte donde especificamos el URL del sitio que estaremos creando. En este caso estamos creando un sitio llamado Sitio 1 y posteriormente creando cuatro grupos en donde los grupos Visitors y Members tienen como dueño al grupo Permissions.


stsadm.exe -o createweb –url “el url del sitio donde crearemos/url del nuevo sitio -lcid 1033 -sitetemplate STS#0  -title “Sitio 1″ -description “” –unique


stsadm.exe -o creategroup -url “el url del sitio donde aplicaremos” -name “Sitio 1 Permissions” -description “Permissions of the site” -ownerlogin “administrator@litwareinc.com” -type “Owner”


stsadm.exe -o creategroup -url “el url del sitio donde aplicaremos” -name “Sitio 1 Owners” -description “Owners of the site” -ownerlogin “administrator@litwareinc.com” -type “Owner”


stsadm.exe -o creategroup -url “el url del sitio donde aplicaremos” -name “Sitio 1 Visitors” -description “Visitors of the site” -ownerlogin “Sitio 1 Permissions” -type “Visitor”


stsadm.exe -o creategroup -url “el url del sitio donde aplicaremos” -name “Sitio 1 Members” -description “Members of the site” -ownerlogin “Sitio 1 Permissions” -type “Member”


 


Personalmente en ocasiones he llegado a pensar, ¿qué es mas complejo?, la tecnología o la psicología, en fin.


¿Cuál es la mejor alternativa? Depende Sonrisa

WSS 3.0 del primo de un amigo

El primo de un amigo comenta que su implementación de WSS 3.0 con SP2 después de 2 o 3 semanas de implementarse en producción muestra comportamiento muy extraño. Sucede que el disco duro del servidor de aplicaciones se ha llenado de forma repentina y sin explicación alguna.

La realidad es que si existen dos explicaciones.

  • La primera es que la implementación WSS 3.0 con SP2 del primo de un amigo careció de planeación y gobernabilidad.
  • La segunda es que la bitácora de rastreo a.k.a trace log ha saturado con archivos e información de trace  el disco duro.

Sucede que WSS 3.0 recién instalado fuera de la caja viene con la configuración de trace log automática de generar 100 archivos de log durante 100 minutos. Si hacemos la matemática de esto podríamos fácilmente identificar porqué se llenó el disco duro estrepitosamente.

La solución es hacerle caso a la herramienta central de administración y en la sección de OperationsDiagnostic logging dar clic al enlace “Learn about using trace log” para entender realmente las implicaciones de especificar el número de archivos de logs que SharePoint va a generar durante un periodo de minutos por archivo, con la finalidad de consolidar en una bitácora informacion de cambios que le permita al administrador de la granja entender comportamientos de procesos y configuracion.

image

Un saludo al primo de mi amigo que se llama Juan para que me entiendas Pedro. Smile

Manipulación programática de archivos de Microsoft Project *.mpp con .NET

Si por alguna extraña razón cósmica en este mundo ultra moderno de la programación de software bajo plataforma .NET  te encuentras con la necesidad de manipular programáticamente archivos de Microsoft Office te recomiendo uses el proyecto open source MPXJ.

La biblioteca MPXJ permite la lectura y escritura de diversos formatos de archivo de Microsoft Project usando un API en .NET o Java.  Estas API ofrecen clases que representan los componentes de un archivo de Project como Tareas, Recursos, Calendario, Asignaciones, etc. Y los métodos para poder acceder, operar y manipular dichos objetos.

Estoy seguro que este modelo de objetos te permitirá darte una idea de cómo inter operar con Project desde tus aplicativos. En mi caso, con la ayuda de @juankaram “que en definitiva fue estratégica su intervención”, tuvimos que integrar en SharePoint un WebPart lector de archivos de Project.

El resultado:

landetrabajo

Orden de instalación de actualizaciones de Office SharePoint Server 2007

Solo por si acaso dejo lo siguiente. Resulta que tuve que realizar una instalación de Microsoft Office SharePoint Server 2007 y después implementar un respaldo de un sitio de publicación desarrollado en otra granja que cuenta con las actualizaciones más recientes. Accedí al MSDN Download Center para descargar MOSS y descargue la versión del disco de instalación que ya viene con el Service Pack 1 integrado, procedí con la instalación y configuración requerida y todo bien. Al restaurar el respaldo mediante stsadm.exe –o restore –filename “xxx.dat” –url “http://xxx” -overwrite la consola me envía un mensaje de error indicando que no se puede restaurar ya que el sitio fue construido bajo una versión o build número 12.0.0.6335 de SharePoint. Acto seguido, decidí implementar las más recientes actualizaciones y a continuación describo el orden.

Pero antes quiero mencionar que te fijes bien en la plataforma de hardware 32bit o 64bit de tu granja ya que los siguientes enlaces que a continuacion describo son solo para 32bit.

Orden de instalación de actualizaciones SharePoint MOSS:

  1. Instalación de MOSS 2007 en Ingles con Service Pack 1 integrado
  2. Instalación del Paquete de idioma de Windows SharePoint Services 3.0
  3. Instalación del Paquetes de idiomas de 2007 Office system para SharePoint Server 2007, Forms Server 2007, Project Server 2007 y SharePoint Server 2007 for Search
  4. Instalación del Windows SharePoint Services 3.0 Service Pack 2 en ingles
  5. Instalación del 2007 Office Servers Service Pack 2 en ingles
  6. Instalación del Paquete de idioma de Windows SharePoint Services 3.0 Service Pack 2 (SP2)
  7. Instalación del 2007 Microsoft Office Servers Language Pack Service Pack 2 (SP2)

Ejecute de nuevo la restauración y listo. Todo quedo restaurado sin problema alguno.