SSD: el síndrome de la Sharepoint dependencia

Sharepoint me proporciona seguridad y me hace sentir más fuerte. Las 10 cosas que más me gustan de Sharepoint.

10 puntos para entender a Project Server 2010

Microsoft Project es quizá la herramienta de gestión de proyectos más conocida y utilizada por los líderes de proyectos...

Diseño Gráfico en SharePoint

Serie de artìculos que nos ayudan a incorporar diseño gráfico en las implementaciones de SharePoint...

Revista CompartiMOSS

Artículos publicados en la revista especializada en SharePoint: CompartiMOSS.

Contacto

Enviame un correo :-)

jueves, 31 de marzo de 2016

¿Cómo actualizar sub sitios existentes cuando modifiqué la plantilla?

Esta pregunta fue realizada en sharepoint.stackexchange.com y me pareció importante compartir un enfoque que he tomado en una situación similar. Comparto la respuesta que dejé en el foro. Pueden verla en:


Transcripción de mi respuesta

Hola.
Estoy trabajando en un proyecto similar:
- Sitio raíz
- Sitios de proyecto
- Plantillas de sitios de proyecto
Es un proyecto de más de un año bastante complejo.

Me he encontrado con el mismo problema y he analizado diferentes alternativas.

No hay forma de resolver eso automáticamente. Para ello deberías usar definiciones de sitios en lugar de plantillas de sitios. Pero es un enfoque excesivamente complejo y muy poco utilizado.

Has hecho muy bien en utilizar tipos de contenido ya que eso resuelve gran parte del problema.

En mi caso he optado por utilizar el modelo de objetos del servidor para hacer los cambios en los sitios de proyecto ya existentes. Me refiero a C# con Visual Studio. Este modelo es muy poderoso y te permite modificar cosas que uno nunca hubiese imaginado.

Resumen del enfoque:

1) Creas un programa en C# para hacer los cambios mediante código. No utilizas configuración.
2) Ese programa posee un LOOP para recorrer todos los sitios de proyecto y aplicar los cambios

Luego de usar este enfoque, he tomado la decisión de hacer todos los cambios en forma programática. Esto facilita mucho el pasaje entre ambientes de prueba y producción.

Entonces el enfoque pasa a ser crear un programa que:

1) Modifique programaticamente tipos de contenido y columnas de sitio
2) Modifique programáticamente los sitios de proyecto (incluso la plantilla). Me refiero a vistas, elementos web, etc.
3) Crea una nueva plantilla basada en el sitio base y elimine la anterior

Con este enfoque el pasaje entre desarrollo y prueba / producción es limpio y rápido. Es muy robusto. Y actualiza automáticamente los sitios existentes. Garantizando al mismo tiempo que los sitios futuros se creen con los nuevos cambios de la plantilla.

Cualquier consulta avisame. 
Tengo muchísimos ejemplos de código para compartir.

lunes, 28 de marzo de 2016

¿Cómo listar las alertas de usuario en una lista en SharePoint con c#?

El objetivo es lista para una lista específica las alertas de diferentes usuarios.

En este ejemplo, a modo de prueba, he configurado una alerta sobre la lista Hitos:


El siguiente código permite listar los usuarios con alertas sobre Hitos:

        public static string listarAlertasLista(SPWeb web, string listaInternalName)
        {
            string alerts = "";
            string listUrl = web.ServerRelativeUrl + "/Lists/" + listaInternalName;
            listUrl = listUrl.Replace("//", "/");
            
            SPList list = web.GetList(listUrl);
            SPAlertCollection alertsColl = web.Alerts;

            alerts += "<span style='color: blue'>Alertas de la lista " + listaInternalName + "</span><br>";
            foreach (SPAlert alert in alertsColl)
            {
                if (alert.ListID == list.ID)
                {
                    alerts += "Usuario: " + alert.User.LoginName + "<br>";
                    alerts += "Tipo: " + alert.AlertType + "<br>";
                    alerts += "Canales: " + alert.DeliveryChannels.ToString() + "<br>";
                }
            }

            return alerts;
        }


El resultado:


viernes, 25 de marzo de 2016

¿Cómo listar los adjuntos de un ítem de lista en c# en SharePoint?

El resultado



El código

        public static string htmlAdjuntos(string lista, int id, int total)
        {
            string html = "";
            if (total > 0)
            {
                using (SPWeb web = SPContext.Current.Web)
                {

                    // Busco el ítem            
                    string listaURL = web.ServerRelativeUrl + "/Lists/" + lista;
                    listaURL = listaURL.Replace("//", "/");
                    SPList listaAdjuntos = web.GetList(listaURL);
                    SPListItem item = listaAdjuntos.GetItemById(id);

                    // Busco adjuntos
                    SPAttachmentCollection adjuntos = item.Attachments;
                    foreach (string adjunto in adjuntos)
                    {
                        string urlAdjunto = SPUrlUtility.CombineUrl(item.Attachments.UrlPrefix, adjunto);
                        SPFile archivoAdjunto = web.GetFile(urlAdjunto);
                        string nombreAdjunto = archivoAdjunto.Name;
                        html += "&nbsp;<a style='border:none;' href='" + urlAdjunto + "'>" + iconoAdjunto(nombreAdjunto) + "</a>";
                    }

                }

            }

            return html;
        }

        public static string iconoAdjunto(string hint)
        {
            string extension = Path.GetExtension(hint).ToLower();
            if (extension != ".doc" && extension != ".docx" && extension != ".xls" && extension != ".xlsx" && extension != ".ppt" && extension != ".pptx" && extension != ".txt" && extension != ".zip" && extension != ".bmp" && extension != ".jpg" && extension != ".jpeg" && extension != ".png")
                extension = "gen";
            if (extension != null) extension = extension.Split('.')[1];
            return icono(hint, "ic" + extension + ".gif");
        }

        public static string icono(string hint, string img)
        {
                return "<img title='" + hint + "' border='none' src='/_layouts/images/" + img + "'/>";
        }

jueves, 19 de noviembre de 2015

¿Cómo crear una vista de hoja de datos y ocultarla en c# en SharePoint 2010?

SPList listaRiesgos = oWebsite.Lists.TryGetList("Issues y riesgos");
System.Collections.Specialized.StringCollection columnas = new System.Collections.Specialized.StringCollection();
columnas.Add("Title");
columnas.Add("Observaciones");
string query = "<Where><And><Neq><FieldRef Name='Estado_Cumplimiento_Riesgo'/><Value Type='Text'>Cerrado</Value></Neq><Neq><FieldRef Name='Estado_Cumplimiento_Riesgo'/><Value Type='Text'>Desestimado</Value></Neq></And></Where><OrderBy><FieldRef Name='Tipo_Riesgo' Ascending='False'/></OrderBy>";
SPView vista = listaRiesgos.Views.Add("mivista", columnas, query, 100, true, false, SPViewCollection.SPViewType.Grid, false);
vista.Hidden = true;
vista.Update();


lunes, 16 de noviembre de 2015

La foto del anillo especial por los cinco años como MVP!

domingo, 25 de octubre de 2015

¿Cómo listas los nombres internos de las columnas de una lista en SharePoint con PowerShell?

$lista = $web.Lists["Issues y riesgos"]
$lista.Fields | Select Title, InternalName | sort InternalName | out-file c:\nombres.txt
NotePad c:\nombres.txt


jueves, 8 de octubre de 2015

Stack Overflow (in Spanish)

jueves, 1 de octubre de 2015

Quinto año de MVP :-)

Muy contento :-)


miércoles, 23 de septiembre de 2015

¿Cómo eliminar manejadores de eventos huérfanos con C# en SharePoint?

Arquitectura de la solución
  • Un sitio raíz
  • Varios sitios hijos
  • Tipos de contenido en el sitio raíz
  • Listas en los sitios hijos que consumen los tipos de contenido del sitio raíz
  • Manejadores de eventos asociados a los tipos de contenido del sitio raíz en forma programática:



El problema

Se presenta un error al tratar de eliminar los eventos asociados el tipo de contenido, propagando el cambio hacia los tipos de contenido descendientes:




El error

Mensaje: Operación no válida dado el estado actual del objeto. Operación no válida dado el estado actual del objeto. Operación no válida dado el estado actual del objeto. Operación no válida dado el estado actual del objeto. Operación no válida dado el estado actual del objeto. Operación no válida dado el estado actual del objeto. Operación no válida dado el estado actual del objeto. Operación no válida dado el estado actual del objeto. Operación no válida dado el estado actual del objeto. Operación no válida dado el estado actual del objeto. Operación no válida dado el estado actual del objeto. Operación no válida dado el estado actual del objeto. Operación no válida dado el estado actual del objeto. Operación no válida dado el estado actual del objeto. Operación no válida dado el estado actual del objeto. Operación no válida dado el estado actual del objeto. Operación no válida dado el estado actual del objeto. 

Stack trace: en Microsoft.SharePoint.SPContentType.PushDownChanges(CodeToPushDownChangesToDerivedCT derivedCTPushdownCode, CodeToPushDownChangesToListCTs listDerivedCTsPushdownCode, Boolean throwOnSealedOrReadOnly, IList`1 exceptions) en Microsoft.SharePoint.SPContentType.UpdateOnWeb(Boolean bPushdown, Boolean ignoreSealedOrReadOnly, Boolean bThrowOnSealedOrReadOnly, Boolean bSetNextChildByteToZero, IList`1 exceptions) en Microsoft.SharePoint.SPContentType.Update(Boolean updateChildren, Boolean ignoreSealedOrReadOnly, Boolean throwOnSealedOrReadOnly, IList`1 exceptions) en Microsoft.SharePoint.SPContentType.Update(Boolean updateChildren, Boolean throwOnSealedOrReadOnly) en EMP_Procesos.Layouts.EMP_Procesos.Upgrade.asociarEventosGovernance(SPSite sitio) en EMP_Procesos.Layouts.EMP_Procesos.Upgrade.b__2()

Source: Microsoft.SharePoint

Target site: Void PushDownChanges(CodeToPushDownChangesToDerivedCT, CodeToPushDownChangesToListCTs, Boolean, System.Collections.Generic.IList`1[System.Exception])



El análisis del problema

Investigando con SharePoint Manager, se observa que hay tipos de contenido en los sitios hijos que tienen un ensamblado erróneo y no tienen los manejadores de eventos. Se observa que la rama de EventReceivers no se puede abrir:



Debería verse así (sitios en que se encuentra bien)



La solución:

Se busca eliminar los manejadores de eventos dentro del XML utilizando este código proporcionado en una respuesta de Stackoverflow:

http://sharepoint.stackexchange.com/a/47408/39542 (se recomienda ver el hilo completo ya que existen varias soluciones que dependen de cada escenario)

var ctG = listaG.ContentTypes["Governance"];
if (ctG.XmlDocuments.Count > 0)
{
  ctG.XmlDocuments.Delete("http://schemas.microsoft.com/sharepoint/events");
  contenido.InnerHtml += "<span>" + oWebsite.Title + ": XML Documents encontrados en Governance</span><br>";
  ctG.Update();
}

El arreglo

Los tipos de contenido se visualizan así en SharePoint Manager luego de la "limpieza"




El resultado

Luego de borrar y volver a asociar los eventos, se observa el XML con el ensamblado correcto y los eventos correctos asociados:


lunes, 21 de septiembre de 2015

¿Cómo listas los manejadores de eventos de los tipos de contenido del sitio raíz en SharePoint con C#?

SPContentTypeCollection tcs = oSiteCollection.RootWeb.ContentTypes;
foreach (SPContentType tc in tcs)
{
  contenido.InnerHtml += "<span><b>" + tc.Name + "</b></span><br>";
  SPEventReceiverDefinitionCollection eventos = tc.EventReceivers;
  foreach (SPEventReceiverDefinition evento in eventos)
  {
    contenido.InnerHtml += "<span>" + evento.Synchronization + "</span><br>";
    contenido.InnerHtml += "<span>" + evento.Class + "</span><br>";
    contenido.InnerHtml += "<span>" + evento.Type + "</span><br>";
  }
}