miércoles, 11 de diciembre de 2013

Entrevista CompartiMOSS

CompartiMOSS es una revista digital especializada en temas de SharePoint y algunas tecnologías relacionadas a esta plataforma de colaboración. En la más reciente edición de la revista del mes de Diciembre se publicó una entrevista que me hicieron en días pasados. 

Les recomiendo ampliamente lean los artículos de esta revista, y claro también lean la entrevista que me hicieron.


jueves, 31 de octubre de 2013

ID4037: The key needed to verify the signature could not be resolved from the following security key identifier

Hace unos días estaba revisando un portal de SharePoint 2013 que había sido configurado para permitir la autentificación mediante Windows Live ID, la autentificación había sido configurada utilizando las siguientes guías:

Configure claims-based authentication using Windows Live ID (SharePoint Server 2010)
Visual guide to Windows Live ID authentication with SharePoint 2010 - part 1

Aunque las guías mencionadas son para SharePoint 2010 funcionan para SharePoint 2013 también, tan es así que el portal estuvo funcionando adecuadamente durante la etapa de desarrollo del  proyecto (algunas semanas) sin embargo de un día para otro dejo de funcionar la autentificación mediante Windows Live ID y en su lugar el portal mostraba el siguiente error cuando un usuario intentaba autentificarse mediante este método.

El mensaje:
ID4037: The key needed to verify the signature could not be resolved from the following security key identifier.
Después de revisar un rato los logs de SharePoint que se generaban al presentarse el error no encontré mayor información acerca del error por lo que decidí revisar los datos de configuración del proveedor de autentificación, sin embargo todo parecía estar correctamente configurado. Por último recordé que al ser esta una instalación de “Staging” los certificados que se utilizan para la configuración son temporales por lo que procedí a revisar  la vigencia de los certificados y efectivamente estaban vencidos.

Una vez descubierta la causa del error es hora de buscar la solución, la cual describo a continuación:

1.- Remover los certificados expirados. Para esto pueden utilizar la consola MMC.exe importando el addin de Certificados, identificar los certificados que ya expiraron y eliminarlos, los certificados deben encontrarse en los siguientes almacenes: Trusted Root Certification Authority, Trusted People y SharePoint.


2.- Una vez que los certificados han sido removidos se debe descargar de nuevo el certificado para posteriormente instalarse en los mismos almacenes. El certificado debe descargarse de la url https://nexus.passport-int.com/federationmetadata2/2007-06/federationmetadata.xml, se debe copiar y pegar en un archivo de texto lo que se encuentra del nodo X509Certificate, se guarda el archivo con extensión .cer.


3.- Una vez que se cuenta con el certificado actualizado se debe instalar en los mismos almacenes de los que se eliminó: Trusted Root Certification Authority, Trusted People y SharePoint.

4.- Por ultimo ejecutamos este pequeño script de PowerShell para actualizar solo el certificado del Trusted Identity Token Issuer

$certfile="C:\temp\LiveID-INT.cer" #path en donde se encuentra el nuevo certificado descargado desde https://nexus.passport-int.com/federationmetadata2/2007-06/federationmetadata.xml
$tokenIssuer=Get-SPTrustedIdentityTokenIssuer -Identity "LiveID INT" #Nombre con el que se registro el Trusted Identity Token Issuer
Set-SPTrustedIdentityTokenIssuer -Identity $tokenIssuer -ImportTrustCertificate $certfile


Despues de realizar estos sencillos pasos el sitio vuelve a funcionar y ya permite la autentificación mediante Windows Live ID

Happy Configuring!

jueves, 8 de agosto de 2013

Error configurando SQL Server Reporting Services 2012 en SharePoint 2010

Hola amigos, el día de hoy con un escenario que encontré hace unos días que intentaba configurar SSRS 2012 en SharePoint 2010.

El escenario es el siguiente: tenía una granja pequeña de SharePoint 2010 SP 2 con dos servidores y un servidor de base de datos con SQL Server 2012 SP 1.

Como parte de los requerimientos era necesario habilitar el servicio de Reporting Services en SharePoint 2010, por lo que procedí a descargar el Add-in de Reporting Services para SharePoint:

Microsoft® SQL Server® 2012 SP1 Reporting Services Add-in for Microsoft® SharePoint®

Sin embargo después de instalar el Add-in en los servidores de SharePoint y seguir el procedimiento standard de instalación de Microsoft, que consiste en la ejecución de los comandos de PowerShell:


Install-SPRSService
Install-SPRSServiceProxy
get-spserviceinstance -all |where {$_.TypeName -like "SQL Server Reporting*"} | Start-SPServiceInstance


Y posteriormente la creación del service application de Reporting Services en el sitio central de administración, noto que no me es posible crearlo, al revisar los servicios iniciados en el servidor me doy cuenta que el servicio SQL Server Reporting Services Service tuvo un error al iniciarse. Como buen consultor intento iniciarlo una vez más (porque todos pensamos que los problemas se resuelven haciendo las mismas cosas muchas veces?) y veo el siguiente error en pantalla:

Pero como siempre, este tipo de mensajes no son de mucha ayuda por lo que revise el visor de eventos de Windows para ver si existe alguna información extra que me ayude a corregir el error, pero solo encuentro el mismo mensaje:

Installation Error: Could not find SOFTWARE\Microsoft\Microsoft SQL Server\110 registry key Error with installing SQL Server Reporting Service Application

Después de un rato de investigación y de no encontrar nada, vuelvo a leer y revisar los procedimientos de instalación (oficiales y no oficiales) y me doy cuenta que algunos blogs hacen referencia a este Add-in, sin embargo otros hacen referencia, implícitamente, al uso de la media de SQL Server 2012, es decir del archivo ISO con que se instaló SQL Server 2012 y lo utilizan para instalar el Add-in de SSRS en los servidores de SharePoint.

Dado que en este punto no sabía que otra cosa intentar más que utilizar los bits de SQL Server 2012 SP 1 para configurar Reporting Services procedo a desinstalar el Add-in:


Y posteriormente utilizando los bits de SQL Server 2012 SP 1 con que se instaló el servidor de base de datos, ejecuto el instalador  en los servidores de SharePoint 2013 y selecciono solo los componentes necesarios de Reporting Services.


Acto seguido vuelvo a ejecutar los comandos de PowerShell y reviso si el servicio fue iniciado adecuadamente, y efectivamente todo funciona como debería.



Ya solo por curiosidad reviso la versión del Add-in instalado y note que si es diferente a la versión que había estado instalando previamente: 


Espero que este post les sirva y ahorre tiempo en el futuro.

Happy configuring!

martes, 23 de julio de 2013

SharePoint 2010 Service Pack 2

El dia de hoy se han hecho públicos los bits del service pack 2 de SharePoint 2010, por lo que a continuación les comparto un enlace de donde pueden descargarlos:

SharePoint Foundation 2010 SP2
SharePoint Server 2010 SP2

En este link pueden encontrar el listado de cambios que se incluyen en el service pack 2

Por su puesto tambien estan disponibles los service pack 2 para los respectivos language packs

Service Pack 2 for Microsoft SharePoint Foundation 2010 Language Pack
Service Pack 2 for Microsoft 2010 Server Language Pack

No olviden primero instalar y probar estos nuevos bits en ambientes de desarrollo y/o pre producción.



Happy updating!

miércoles, 10 de julio de 2013

Error <nativehr>0x80070003</nativehr><nativestack></nativestack> al restaurar una colección de sitios

Hace algunos días intentando restaurar una colección de sitios desde un respaldo generado en otra granja, me encontré con el siguiente error:


<nativehr>0x80070003</nativehr><nativestack></nativestack> At line:1 char:1 + Restore-SPSite http://webapplication:12345/sites/sitecollection_name -Pat ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~ + CategoryInfo : InvalidData: (Microsoft.Share...dletRestoreSite: SPCmdletRestoreSite) [Restore-SPSite], DirectoryNotFoundException + FullyQualifiedErrorId : Microsoft.SharePoint.PowerShell.SPCmdletRestoreSite
La instrucción de PowerShell que estaba utilizando era algo como lo siguiente

Restore-SPSite -Identity http://server_name/sites/sitecollection -Path c:\temp\site_name.bak


Buscando un poco en la web se encuentran algunas referencias de dos posibles razones y formas de corregir este error:

1.- Managed Path incorrecto. Esto en caso de que el managed path "sites" no estuviera registrado como un path valido en el web application, la solución evidentemente es agregarlo. No era mi caso

2.- Permisos. Ejecutar el comando de Restore-SPSite con un usuario sin permisos; la solución obviamente es ejecutar el comando con un usuario administrador de la granja de SharePoint. Desafortunadamente tampoco era mi caso.

La forma en que yo pude realizar satisfactoriamente la restauración de la colección de sitios en la granja de destino fue a partir de un backup realizado desde la base de datos de contenido, a continuación enumero los pasos a seguir para realizar este workaround.

1.- Identificar la base de datos de contenido que contiene la coleccion de sitios que deseamos restaurar en la granja destino.
2.- Realizar un full backup de esta base de datos mediante SQL Server Management Studio (o mediante t-sql).
3.- Mover el respaldo realizado a una ubicacion que pueda ser accedida desde la base de datos de la granja destino.
4.- Restaurar la base de datos de contenido en una nueva base de datos dentro de la instanacia de SQL Server de la granja de SharePoint destino.
5.- Montar la base de datos con el siguiente comando de PowerShell:

Mount-SPContentDatabase "Nombre_de_la_base_de_datos_de_contenido_restaurada"  -WebApplication http://webapplication_destino

Por ultimo es importante recordar que una base de datos de contenido puede contener mas un site collection por lo que si este es su caso, desafortunadamente tendrán que borrar manualmente las colecciones de sitios que no utilicen.

Referencias:
Restore-SPSite
Mount-SPContentDatabase

Happy Coding!

viernes, 28 de junio de 2013

SkyDrive Pro app para Windows 8 e iOS

Tal como lo dice el titulo de este post, el día de ayer Microsoft libero la app de SkyDrive Pro para Windows 8 y para iOS, las cuales pueden ser descargadas desde sus respectivos stores.


Desafortunadamente estas apps solo funcionan para suscriptores de Office 365 que utilizan SharePoint Online (SPO), pero esperemos que en un futuro cercano Microsoft agregue soporte para deployments on-premises

Happy testing!

sábado, 22 de junio de 2013

Listar folders utilizando la API REST de SharePoint Online

En ocasiones es necesario navegar programáticamente a través de la estructura de carpetas de una librería de documento o de una carpeta en específico, esta actividad es bastante sencilla realizándola mediante la API de servidor de SharePoint con la que hemos venido trabajando los últimos años.

Sin embargo a partir del nuevo paradigma de desarrollo de apps para SharePoint 2013, nos enfrentamos a nuevas formas de realizar los que antes ya hacíamos con API del servidor utilizando y nos lleva a utilizar métodos mucho más estándares y que son compatibles con el nuevo modelo de apps, me refiero a utilizar la API REST de SharePoint 2013.

En esta ocasión voy a ejemplificar como cumplir con la tarea de listar las carpetas de una librería de documentos mediante la api REST, lo primero que necesitamos en comenzar a construir la consulta REST a utilizar contra una librería de documentos, en principio la siguiente consulta nos mostraría la información de una librería de documentos:

https://myportal.sharepoint.com/_api/web/GetFolderByServerRelativeUrl('/Folders%20Library')

Donde “Folders Library” es el nombre de la librería de documentos de la cual quiero mostrar sus carpetas. Noten el uso del método GetFolderByServerRelativeUrl que se encuentra a nivel del “objeto” Web y el cual nos permite abrir un folder en particular, en este caso la librería de documentos en si misma.


Lo siguiente es utilizar la opción $expand para acceder a la “propiedad” Folders de la librería de documentos, algo como lo siguiente: https://myportal.sharepoint.com/_api/web/GetFolderByServerRelativeUrl('/Folders%20Library')?$expand=Folders


Por ultimo solo usamos la opción $select para seleccionar los campos que necesitamos, recuerden que siempre debemos limitar la cantidad de información que solicitamos al servidor, solo para fines de optimizar nuestro desarrollo, la url de consulta final:

https://myportal.sharepoint.com/_api/web/GetFolderByServerRelativeUrl('/Folders%20Library')?$select=Folders/name,Folders/ServerRelativeUrl,Folders/ItemCount&$expand=Folders

Una vez que tenemos lista la consulta solo agrego un código de ejemplo que pinta las carpetas que se encuentran dentro de la librería de documentos como un listado, Show me the money!

El script:









El resultado:

Happy Coding!

miércoles, 5 de junio de 2013

Recomendaciones para despliegue SharePoint 2013

Recientemente me he embarcado en un proyecto que implica el despliegue de una granja de SharePoint 2013 con 16  servidores, si, como lo leyeron… 16 servidores!

Dado que el propósito de esta arquitectura será servir como un repositorio central de una gran cantidad de documentos, es decir Archiving, se ha diseñado una arquitectura que a grandes rasgos es integrada por los siguientes servidores:

3 servidores Web Front End
2 Servidores de Aplicación
11 Servidores dedicados para el servicio de búsqueda

Sin lugar a dudas más adelante estaré comentando como me ha ido con este despliegue de SharePoint, por el momento comparto algunos de los enlaces que a mí me han servido bastante para dimensionar y diseñar este monstruo de granja:


Adicionalmente, y dado que es un proyecto que estamos realizando en conjunto con MCS (Microsoft Consulting Services) el equipo de soporte premier me ha recomendado instalar los siguientes fixes liberados hasta el momento, tómenlos en cuenta para sus implementaciones:



Happy Configuring!

miércoles, 29 de mayo de 2013

SharePoint 2013 - Recuperar imagenes de libreria de imagenes mediante REST

En estos últimos días me he estado jugando un poco con la API REST para crear funcionalidad para SharePoint Online en donde, como todos ustedes ya saben, no se puede desplegar soluciones full trust.

La API REST de SharePoint es tan fácil de usar que combinándola con un poco de JavaScript y utilizando alguno de los frameworks más populares como jQuery, Knockout, JsRender, etc, etc, se pueden lograr cosas bastante funcionales y sobre todo muy visuales.

En esta ocasión voy a compartir un ejemplo de cómo recuperar las Urls de las imágenes que se encuentran en una librería de imágenes para mostrarlas en una WebPart.

Lo primero que debemos hacer y tal vez lo más “difícil” es construir la consulta ODATA que recupere los metadatos que necesitamos para obtener las urls de las imágenes.

En mi ejemplo la librería de imágenes se llama “Car Images” y se encuentra dentro de un subsitio WXYZ (el nombre de sus subsitio), por lo que la url podría quedar como la siguiente:

https://sitioprincipal/subsitio/_api/web/Lists/getbytitle('Car%20Images')/items?$Expand=File&$select=File/ServerRelativeUrl

La parte fundamental es la que esta marcada en negro, con esa consulta podemos recuperar las urls de las imágenes, sin embargo existe el inconveniente de que las urls que recuperamos pertenecen a las imágenes originales y que pueden ser muy grandes (como en mi caso) por lo que lo ideal es recuperar las imágenes pequeñas o thumbnails que se crean automáticamente cuando los archivos de imágenes se cargan en la biblioteca. Para lo anterior se debe modificar un poco la consulta para acceder a la carpeta “_t” que es en donde se encuentran esas imágenes miniatura, y quedaría de la siguiente manera:

https://sitioprincipal/subsitio/_api/web/GetFolderByServerRelativeUrl('Car%20Images/_t')?$Expand=Files&$select=Files/ServerRelativeUrl

Noten el uso de la función GetFolderByServerRelativeUrl para acceder a la carpeta “_t” y enumerar las imágenes miniatura. Una vez que ya tenemos la consulta lo siguiente es escribir un Html muy sencillo en el que se ejecute esta consulta y se pinten las imágenes en el HTML. Algo como lo siguiente podría funcionar:






Y si ponemos este Html dentro de un content editor...funciona!

Nótese que en este caso por simplicidad solo concateno texto para formar el HTML, algo que podría hacerse mucho mas elegante con Knockout por ejemplo, pero eso sera en un siguiente post.

Happy coding!

domingo, 12 de mayo de 2013

Webcast - Nuevo modelo de aplicaciones con Sharepoint 2013

Hola amigos, quiero invitarlos al Webcast Nuevo modelo de aplicaciones con Sharepoint 2013, que estaré impartiendo como parte del ciclo de Webcast de Visual Studio 2012.

El Webcast se llevara a cabo el Lunes 27 de Mayo del 2013 a las 2:00 PM (GMT-06:00) hora de la ciudad de México.

Les comparto la URL para el registro:

Espero contar con su asistencia

Happy code!

domingo, 5 de mayo de 2013

SharePoint 2013 REST - Feed format not supported

Si están comenzando  a adentrarse en la creación de apps para SharePoint 2013, tal vez de las operaciones más básicas que están realizando es consumir la api REST de SharePoint, y dada la facilidad con que se puede hacer una consulta ODATA a través de la barra de navegación del explorador es muy probable que se enfrenten a la siguiente situación cuando crean una consulta:

Internet Explorer muestra el mensaje: Feed format not Supported.

Por suerte es bastante fácil solucionar esto, simplemente sigan los siguientes pasos:

En el menú Tools de Internet Explorer seleccionen la opción Internet Options

En la pestaña Content seleccionen la opción Feeds and Web Slices

Asegúrense que la opción Turn on feed Reading view no está seleccionada

Eso solucionara este pequeño inconveniente

Happy Coding!

miércoles, 1 de mayo de 2013

Recomendaciones para iniciar a construir apps para SharePoint 2013

Algo de lo cual me he dado cuenta últimamente es que desafortunadamente los desarrolladores de SharePoint que solo desarrollan para esta plataforma tienen nulos o vagos conocimientos de algunas otras tecnologías/plataformas/frameworks y es que haciendo una reflexión del día a día al que nos enfrentamos los desarrolladores SharePoint (me incluyo) lo común es crear elementos tales como:

  • Features
  • Event Receivers
  • Jobs
  • Web Services
  • WebParts
  • Workflows
  • Master Pages
  • Paginas (ASPX)
  • User Controls (ASCX)
  • Etc, etc
Además de lo acotado que es el ámbito técnico de los elementos de desarrollo de SharePoint, y por favor no me mal entiendan, la variedad de soluciones que se pueden construir con y sobre SharePoint es casi ilimitada sin embargo los elementos a utilizar tecnológicamente hablando son relativamente pocos (los listados arriba), lo que ocasiona que con el tiempo nos encasillemos en cosas como el desarrollo ASP.NET “tradicional”.

Dicho y aclarado lo anterior, no es de extrañarse la renuencia de los desarrolladores ahora que Microsoft quiere evangelizarlos para construir, diseñar y pensar en términos de apps en lugar de soluciones tradicionales (Farm Solutions) ya que las Apps implican muchos conceptos y tecnologías nuevos, y a veces hasta desconocidos, para este grupo de desarrolladores.

Es imprescindible que comencemos a aprender todos estos conceptos/frameworks/tecnologías ASAP si no queremos quedarnos fuera de la jugada y con el tiempo ir quedando relegados. Evidentemente no es posible aprender todo en una noche (o acaso les funciono cuando estudiaban la noche antes del examen? ) pero si es posible ir diseñando un track de auto capacitación que nos permita acercarnos a esta nueva apuesta de Microsoft. 


A continuación les menciono y comparto un primer paquete de enlaces de los temas y herramientas con los que un “desarrollador SharePoint 2013” debería estar familiarizado, en posts subsecuentes iré agregando algunos otros enlaces recomendados junto con los ejemplos de desarrollos para SharePoint 2013, por el momento revisen lo siguiente:

Temas
ODATA
ASP.NET MVC 5
How to: Complete basic operations using SharePoint 2013 REST endpoints
Web API
Jquery

Herramientas
Fiddler
ODATA QueryBuilder
Internet Explorer Developer Tools
Chrome Developer Tools

Adicionalmente es muy recomendable que si tienen la oportunidad de adquirir una subscripcion al sitio de entrenamiento en linea de Pluralsight lo hagan sin dudarlo, tiene una amplia biblioteca de recursos tecnicos de muy buena calidad.

Por el momento pueden iniciar con estos temas, si consideran que hay alguna herramienta o tema fundamental para iniciar el desarrollo de Apps que no haya mencionado no duden en comentar!

Happy Coding!

martes, 5 de marzo de 2013

Rich Text Field in SharePoint Document Library

Se han visto en la necesidad de agregar una columna de texto enriquecido a una librería de documentos de SharePoint? 

Si es así, se habrán dado cuenta que las librerías de documentos permiten crear un campo de texto multilinea pero no permite utilizar texto enriquecido.

De manera predeterminada las librerías de documentos de SharePoint no permiten utilizar el texto enriquecido en una columna. De hecho si miramos dentro de las propiedades del campo en la librería de documentos, utilizando PowerShell, veremos que en efecto los valores de los campos no son los adecuados para poder ingresar texto enriquecido en la columna recién creada.



Sin embargo siempre se puede utilizar un poco de scripting para "corregir" todo. A continuación el fragmento de PowerShell que modifica este comportamiento.

cls
$site= Get-SPSite -Identity http://sharepoint/sites/Test/
$web = $site.RootWeb

$lists= $web.Lists["Documents"]
$field=$lists.Fields["RichTextColumn1"]

$field.RichText=$True
$field.RichTextMode="FullHtml"
$field.UnlimitedLengthInDocumentLibrary=$True

$field.Update()



Adicionalmente deben tener cuidado con la propiedad UnlimitedLengthInDocumentLibrary, ya que podría causar problemas de performance si el usuario decide agregar mucho texto en esa columna o si esta columna será utilizada como metadato de alguno de los documentos de Office, ya que estos últimos tienen la restricción de solo soportar 255 caracteres como máximo.

Happy Scripting!

martes, 5 de febrero de 2013

Exámenes liberados para SharePoint 2013

Tal vez aún no se hayan dado cuenta, pero un par de exámenes de SharePoint 2013 ya fueron liberados desde el 1 de Febrero. Los exámenes liberados son:

Estos exámenes forman parte del path de certificación para MCSM de SharePoint


Adicionalmente, se enviaron los resultados para los que presentaron alguno de estos exámenes el pasado noviembre de 2012, cuando todavía se encontraban en fase beta. Yo presenté y pasé el examen Core Solutions of Microsoft SharePoint Server 2013, además de poder contribuir a generar feedback a Microsoft para ese examen.

Desafortunadamente los exámenes del path de certificación de desarrollo aún no han sido liberados

Pues a preparar los exámenes!!!

viernes, 18 de enero de 2013

Pruebas unitarias con SharePoint Emulator Package

No si ustedes hayan notado el mes pasado (con todas las fiestas que había) que el equipo de Visual Studio anuncio el paquete de SharePoint Emulators de Visual Studio 2012 para SharePoint 2010.

De entrada este paquete solo aplica para SharePoint 2010 y utilizándolo en Visual Studio 2012. Es comprensible que este paquete solo aplique para SharePoint 2010, dado el poco tiempo que lleva SharePoint 2013 liberado, además de que la finalidad del emulador es poder probar código de servidor, mismo que Microsoft desalienta escribir para SharePoint 2013.

Este paquete se puede instalar a través de NuGet. Solo tienen que buscarlo y aparece dentro de los resultados.

  
En el pasado había sido bastante difícil aislar los componentes SharePoint de una solución para realizar pruebas unitarias, debido a que estos componentes dependen enormemente de SharePoint, es decir, para poder realizar la ejecución de pruebas de esos componentes era necesario tener instalado SharePoint.
 
SharePoint Emulators Package nos permite crear pruebas unitarias y ejecutarlas sin tener instalado un ambiente de SharePoint, este paquete se basa en el concepto de Shims de Microsoft Fakes para crear un contexto (un conjunto de Shims) en memoria de los objetos más comunes dentro de la API de SharePoint. Con lo que, para crear una prueba unitaria que utiliza objetos de la API de SharePoint lo único que debe hacer es encerrar el código que estamos probando dentro de un SharePoint Emulator Scope.

[TestMethod]
public void CreateList()
{
	using (SharePointEmulationScope scope = new SharePointEmulationScope(Microsoft.QualityTools.Testing.Emulators.EmulationMode.Enabled))
	{
		using (SPSite site = new SPSite("http://UrldePrueba/"))
		{
			using (SPWeb web = site.OpenWeb())
			{
				Assert.IsNotNull(web);

				//Definiendo la lista
				Guid listId = site.RootWeb.Lists.Add(listName, listName, SPListTemplateType.GenericList);
				SPList list = site.RootWeb.Lists[listId];
				Assert.IsNotNull(list);
				Assert.AreEqual(list.Title, listName, "Bad list name!");

				//agregando los campos a la lista
				list.Fields.Add("Code", SPFieldType.Number, true);
				list.Fields.Add("Name", SPFieldType.Text, true);
				list.Fields.Add("Description", SPFieldType.Text, true);

				//agregando dos nuevos elemento a la lista
				SPListItem item1 = list.Items.Add();
				item1["Code"] = 1;
				item1["Name"] = "West";
				item1["Description"] = "West Region";
				item1.Update();

				SPListItem item2 = list.Items.Add();
				item2["Code"] = 1;
				item2["Name"] = "East";
				item2["Description"] = "East Region";
				item2.Update();

				Assert.AreEqual(list.ItemCount, 2, "Bad number of items");
			}
		}
	}
}


Como mencionaba antes, este paquete solo contiene los Shims para los objetos de uso más común dentro de la API de SharePoint, por lo que habrá casos es los que al hacer uso de ciertos métodos o propiedades, que devuelven un tipo de objeto que no tiene su correspondiente Shim dentro del emulador,  obtendremos excepciones de tipo NotSupportedException, como por ejemplo al intentar utilizar el método GetItems de un objeto SPList, que devuelve un objeto de tipo SPListItemCollection.


El siguiente código muestra el método que se está probando, en la línea 17 está la llamada al método GetItems que lanzará la excepción.
public string GetNameByCode(string listName, SPWeb web, int code)
{
	SPList list = web.Lists[listName];

	var listQuery = new SPQuery
	{
		Query = String.Format(
			"" +
			"" +
			"" +
			"{0}" +
			"" +
			"", code)
	};

	string name = string.Empty;
	foreach (SPListItem item in list.GetItems(listQuery))
	{
		name = item["Name"].ToString();
	}

	return name;
}


Lo genial de esto, es que es posible inyectar Shims al Emulador para los tipos no soportados, como por ejemplo para SPListItemCollection, de la forma tradicional, es decir usando Shims, como se aprecia de las líneas 41 a la 50
[TestMethod]
public void SearchItemById()
{
	int searchById = 2;

	using (SharePointEmulationScope scope = new SharePointEmulationScope(Microsoft.QualityTools.Testing.Emulators.EmulationMode.Enabled))
	{
		using (SPSite site = new SPSite("http://UrldePrueba/"))
		{
			using (SPWeb web = site.OpenWeb())
			{
				Assert.IsNotNull(web);

				//Definiendo la lista
				Guid listId = site.RootWeb.Lists.Add(listName, listName, SPListTemplateType.GenericList);
				SPList list = site.RootWeb.Lists[listId];
				Assert.IsNotNull(list);
				Assert.AreEqual(list.Title, listName, "Bad list name!");

				//agregando los campos a la lista
				list.Fields.Add("Code", SPFieldType.Number, true);
				list.Fields.Add("Name", SPFieldType.Text, true);
				list.Fields.Add("Description", SPFieldType.Text, true);

				//agregando dos nuevos elemento a la lista
				SPListItem item1 = list.Items.Add();
				item1["Code"] = 1;
				item1["Name"] = "West";
				item1["Description"] = "West Region";
				item1.Update();

				SPListItem item2 = list.Items.Add();
				item2["Code"] = 2;
				item2["Name"] = "East";
				item2["Description"] = "East Region";
				item2.Update();

				Assert.AreEqual(list.ItemCount, 2, "Bad number of items");

				//Agregamos el Shimp para el objeto SPListItemCollection
				if (scope.EmulationMode == EmulationMode.Enabled)
				{
					var fakeList = new ShimSPList(list);
					fakeList.GetItemsSPQuery = (query) =>
					{
						var shim = new ShimSPListItemCollection();
						shim.Bind(new[] { list.Items[0], list.Items[1] });
						return shim.Instance;
					};
				}

				RegionGateway gateway = new RegionGateway();

				//Ahora al realizar la llamada al metodo GetNameByCode, no se lanzara la excepcion
				string result = gateway.GetNameByCode(listName, site.RootWeb, searchById);
				Assert.AreNotEqual(string.Empty, result, true, "Search Failed!");


				Region searchItem = gateway.GetRegionById(listName, web, 1);
				Assert.IsNotNull(searchItem);
				Assert.AreEqual("West", searchItem.Name, true);
			}
		}
	}
}

Sin duda alguna un importante paquete que debiéramos usar desde ya para las pruebas unitarias de nuestro código. Ahora lo importante sería preguntar para cuando este paquete estará disponible para SharePoint 2013.

Por último les comparto el proyecto de Visual Studio para que vean el código y puedan analizarlo mejor.


Referencias

Happy Code!

miércoles, 9 de enero de 2013

JqGrid y la API REST de SharePoint 2013

El motivo de este post es mostrar un ejemplo de como combinar el uso del jqGrid obteniendo datos de una lista de SharePoint a través de la API REST.

Antes que nada, supongo que muchos de ustedes conocen el jqGrid, si no es así, se están perdiendo de un plugin de jquery bastante interesante, muy fácil de usar y con bastantes características como:

  • Formatear celdas
  • Reordenar columnas
  • Menús contextuales para filas
  • Barras de menús personalizadas
  • Carga de datos desde diferentes fuentes como XML, JSON, etc
  • Multiseleccion
  • Resizing
  • Edición en línea
  • Agrupación
  • Búsqueda
  • Paginación
  • Y un largo etcétera.

Lo anterior combinado con la practicidad de la nueva API REST de SharePoint 2013 permite a los desarrolladores crear aplicaciones realmente sorprendentes.

Escenario:
Tengo un sitio de SharePoint con una lista llamada Sales con las columnas y datos que se aprecian en la imagen

Requerimiento:
Es necesario mostrar en una pagina, una vista de la lista utilizando alguna de las características arriba mencionadas, como ordenación, menús contextuales, multiseleccion, etc.

Solución:
Como siempre y para cualquier problema, no hay una solución única, pero yo me inclinaría por usar jqGrid, porque la solución es muy sencilla, fácil de codificar y ni siquiera requiere crear un wsp o una App (cosa que hare en otro post) que se instale y despliegue en la granja.

Solo hare uso de la webpart Script Editor para agregar un poco de HTML y JavaScript a una pagina cualquiera de SharePoint.


A continuación el código completo utilizado:


 



 

 




La explicación:
Primero agregamos algunas referencias a los archivos js y css, tanto del grid como de jquery

 



 

 

Luego agregamos el código para configurar el jqGrid, es decir las columnas, el ordenamiento, etc, etc. y el código para realizar la llamada REST y manejar la respuesta para hacer el Binding de datos JSON con el grid
$(onPageLoad);

//funcion que se ejecuta en el evento onLoad de la pagina
function onPageLoad()
{
 //adjuntamos a el evento onclick del boton 'getSales' la funcion getSales()
 $("#getSales").click(getSales);
   $(document).ready(function () {
   //configuramos el jqGrid
    $("#SalesTable").jqGrid({
    datatype: 'local',
    autowidth: true,
    height: 230,
    colNames: ['ID', 'Order Date', 'Region', 'Representative', 'Item', 'Units', 'Unit Cost', 'Total'],
    colModel: [
     { name: 'ID', index:'ID', width: 80 , sorttype:"int"},
     { name: 'Title', width: 80 , sorttype:"date"},
     { name: 'Region', width: 80 },
     { name: 'Rep', width: 80 },
     { name: 'Item', width: 80 },
     { name: 'Units', width: 80 },
     { name: 'Unit_x0020_Cost', width: 80 },
     { name: 'Total', width: 80 , sorttype:"float"},
    ],
    caption: 'Sales via OData'
  });
   });
}

//funcion que se ejecuta cuando hacemos click en el boton 'Obtener Ventas'
function getSales(){
 //Url REST de la consulta que estamos haciendo, recuperamos los elementos de la lista 'Sales'
 var requestUri = "http://sp2013app/_api/web/lists/getByTitle('Sales')/items/";
 //Se establece el header ACCEPT de manera adecuada
 var requestHeaders={
      "ACCEPT":"application/json;odata=verbose",
 }
 //se realiza la llamada ajax mediante jquery
 $.ajax({
 url: requestUri,    //Url de la consulta a realizar
 type:"GET",      //tipo de la llamada
 contentType:"application/json", //el tipo de contenido que esperamos recuperar, JSON
 headers: requestHeaders,  //headers correctos
 error:onError,      //en caso de error se ejecuta la funcion onError()
 success: onGetSalesSuccess  //en caso de exito, se ejecuta la funcion onGetSalesSuccess()
 }); 
}

//funcion que se ejecuta en caso de que la llamada REST sea exitosa
function onGetSalesSuccess(data){
 if(!data)return;
  //por cada uno de los resultados obtenidos se agrega una fila al jqGrid
  $.each(data.d.results,function(index, value){
   $("#SalesTable").jqGrid('addRowData', value.ID, value);
  });
 $("#SalesTable").jqGrid('SalesTable','#pager2',{edit:false,add:false,del:false});
}

function onError(xhr, status){
 alert(xhr.response.message);
}

Y por ultimo tenemos el código HTML que sirve como contenedor del grid, me refiero al input, la tabla y el div. Solo basta descomentar el código HTML al ser usado


El resultado:


Happy Coding!

viernes, 4 de enero de 2013

HTML Field Security en SharePoint 2013

Una de las nuevas características en el área de Web Content Management en SharePoint 2013 es que ahora existe una opción llamada HTML Security Settings que se encuentra en la sección de configuración  de administradores de la colección de sitios, por lo que evidentemente se debe contar con este rol para utilizarla.
 
En SharePoint 2013 los creadores de contenido de un sitio puede agregar iframes en cualquier página, ya sea utilizando la opción Embed Code del menú Insert del Ribbon, o utilizando la nueva webpart Script Editor.

 
Hasta aquí ninguna novedad, en el pasado también se podían agregar iframes a una página de SharePoint, obviamente no utilizando las opciones arriba descritas ya que estas son nuevas en SharePoint 2013, pero si se podía hacer. Lo que la opción HTML Security viene a cubrir era la necesidad de los administradores de SharePoint (esos tipos a los que cualquier toque de creatividad les molesta) de poder restringir los dominios a los cuales se puede agregar o referenciar dentro de un iframe en un sitio de SharePoint.
 
Este setting permite habilitar a los usuarios con rol de "Contributors" el poder agregar iframes a partir de un listado de dominios permitidos, poder referenciar cualquier dominio o no poder insertar iframes con contenido externo a SharePoint en absoluto. La opción por default es permitir a los contribuidores agregar iframes con un listado de sitios también predefinido, como se aprecia en la imagen. 
 
Para este ejemplo voy a agregar un iframe a una página de SharePoint referenciando uno de mis sitios favoritos, Channel 9. Aunque como se puede apreciar en la imagen, obtendré un mensaje indicándome que no cuento con los permisos suficientes para agregar el iframe.
 
Lo que se debe hacer es ir a apartado de configuración de HTML Security Settings y agregar el dominio channel9.msdn.com (para este ejemplo), y acto seguido intentar de nuevo agregar el iframe.
 
Y con esto podemos ya agregar satisfactoriamente una referencia a contenido externo, de manera un poco más ordenada.
 

 
Un último comentario es que este setting solo aplica/restringe a los usuarios con el rol de "Contributors", es decir que si eres el dueño del sitio o un site collection administrator, ni te preocupes por este tipo de limitantes que solo aplican a los simples mortales. Lo que debería preocuparte es revisar tu modelo de gobernabilidad en SharePoint.
 
Happy Configuring! 

Etiquetas

SharePoint 2010 (38) Microsoft (32) Desarrollo SharePoint (31) Gerardo Reyes Ortiz (27) SharePoint (20) SharePoint 2013 (18) Errores SharePoint (12) México (10) PowerShell (9) Silverlight (8) Visio Services (7) Features (6) MVP (6) Silverlight 3 (6) WebCast (6) Workflows (6) Configuracion SharePoint 2010 (5) D.F. (5) API REST (4) Configuracion SharePoint 2010; (4) Troubleshooting (4) Visual Studio 2010 (4) Visual studio (4) WSS (4) Web parts (4) Apps (3) Comunidad SharePoint (3) Configuración SharePoint 2013 (3) ODATA (3) SharePoint Server (3) SharePoint; Instalación SharePoint; Troubleshooting; Search Service (3) Silverlight 3.0 (3) Silverlight Toolkit (3) WebParts (3) javascript (3) jquery (3) Eventos SharePoint (2) Office 2010 (2) PeoplePicker (2) REST (2) SQL Server (2) Scripting (2) Search Service Application (2) SharePoint Designer (2) UPA (2) UPS (2) Workflows SharePoint (2) host header (2) Apps Development (1) Big Bang (1) CAS (1) CSOM (1) Codeplex (1) CompartiMOSS (1) Configuracion SharePoint 2010; Errores SharePoint (1) Configuracion SharePoint 2010; SharePoint 2010 (1) Custom Actions (1) Custom Editor Parts (1) Delegate Controls (1) Deployment (1) DisableLoopbackCheck (1) Document Library (1) Entrevista (1) Examenes de Certificación (1) Extract WSP (1) FBA (1) FS4SP (1) Fakes (1) Fast Search Server 2010 For SharePoint (1) Fiddler (1) HTTP.SYS (1) HTTPS (1) JSON (1) Language Pack's (1) Latam (1) MAXDOP (1) MCSM (1) MSExpertos (1) MVC (1) Microsoft México (1) Microsoft; Codeplex; Screencast; (1) My Sites (1) SQL Server 2012 (1) SQL Server Reporting Services (1) Screencast (1) Screencast; (1) Service Applications (1) Service Pack (1) SharePoint 2007 (1) SharePoint 2010 SP 1 (1) SharePoint API (1) SharePoint Conference (1) SharePoint Emulators (1) SharePoint Farm (1) SharePoint Health Analyzer (1) SharePoint Magazine (1) SharePoint Online (1) SharePoint Search (1) SharePoint Test (1) SharePoint; Desarrollo SharePoint (1) Shims (1) Simposio (1) Simposio Latinoamericano (1) SkyDrive Pro (1) Soporte Microsoft (1) Templates (1) Tip (1) VSeWSS (1) Virtual Machine (1) Visual Studio 2012 (1) WCF (1) WSS; IIS 7 (1) Web API (1) Web Content Management (1) Web Services (1) Windows 8 (1) Windows Live ID (1) Xml (1) appcmd (1) iOS (1) jqGrid (1) onload function (1)