REST API en SharePoint 2013 II:CRUD sobre listas

Si en el anterior Post vimos como realizar consultas básicas de lectura sobre listas utilizando REST, ahora vamos a ver cómo realizar operaciones de creación, actualización, eliminación e inserción con listas de SharePoint. La construcción de la petición para métodos HTTP de tipo GET es más sencilla que para los tipos POST, ya que éstos van a requerir por un lado la obtención del “Form Digest” que nos permitirá realizar este tipo de operaciones, y además será necesario incluir información adicional en las cabeceras JSON y un bloque de datos para algunas peticiones.

Siguiendo el ejemplo del Webpart anterior, vamos a extender el código para implementar la nueva funcionalidad.

Form Digest

Las peticiones PUT y POST van a requerir que incluyamos un valor adicional en la cabecera de la petición, del tipo X-RequestDigest: formDigest, donde éste último parámetro lo obtendremos tras realizar una petición al servicio. Esta petición hay que hacerla cada vez que queramos ejecutar una acción de tipo POST y PUT, por lo que la vamos a encapsular en una función reutilizable:

function getFormDigest() {
console.log("getFormDigest");
var digest = '';

$.ajax({
url: "/_api/contextinfo",
type: "POST",
headers: { "accept": "application/json; odata=verbose" },
dataType: "json",
success: function (data) {
if (data.d) {
digest = data.d.GetContextWebInformation.FormDigestValue;
console.log("FormDigest success");
}
},
error: function (xhr) {
console.error(xhr.status + ': ' + xhr.statusText);
},
async: false
});

return digest;
}

En este caso, la url a la que atacamos es “/api/contextinfo”, y podemos en tiempo de ejecución ver todo lo que nos devuelve, aparte del valor Form Digest. imagePor un lado tenemos el atributo FormDigestTimeoutSeconds, que es el tiempo que va a ser válido el Form Digest antes de que caduque, por lo que tendremos que realizar la operación deseada antes de que expire este tiempo (1800 segundos). Por otro lado tenemos el atributo LibraryVersion, que nos indica la versión de las librerías REST. Además nos da otros valores, como por ejemplo la url de nuestro sitio, etc.


Creación de listas


El primer cambio que vamos a añadir es la posibilidad de crear una lista genérica. Para ello, vamos a modificar el control del Webpart para añadir un botón que lance el código:


image


Y en el código javascript añadimos la función:


function createBasicList() {
console.log("createBasicList");
var listName = prompt("Enter list name");

if (listName && listName != '') {
var digest = getFormDigest();
if (digest && digest != '') {
var jsonBody = {
'__metadata': { 'type': 'SP.List' },
'BaseTemplate': 100,
'Title': listName,
'Description': ''
};
$.ajax({
url: "/_api/web/lists",
type: "POST",
headers: {
"content-type": "application/json;odata=verbose",
"accept": "application/json; odata=verbose",
"X-RequestDigest": digest, "If-Match": "*"
},
data: JSON.stringify(jsonBody),
success: function (data) {
if (data.d) {
console.log("List created");
alert("List created");
}
},
error: function (xhr) {
console.error(xhr.status + ': ' + xhr.statusText);
}
});
}
}
}

Lo primero que hemos hecho es obtener el Form Digest que vamos a usar. Posteriormente definimos el body de la petición, con sus metadatos y atributos de la lista que vamos a crear (La plantilla, el título y la descripción). Indicamos en la función Ajax que el tipo de petición es POST, y en la cabecera añadimos el tipo de contenido del resultado, y el X-RequestDigest, utilizando el valor obtenido anteriormente.


Al ejecutarlo, introducimos un nombre de una lista que no exista, y veremos el resultado (satisfactorio, o un error).


image


En caso de obtener un error, es necesario leer el log de SharePointimage, ya que no vamos a obtener el detalle del mismo en el resultado de la operación. Si la cosa se complica y no sale a la primera, paciencia y a depurar el código Javascript.


También hay que tener en cuenta que no es posible indicar algunos parámetros en la petición, como por ejemplo la fecha de última modificación. Es decir, no vamos a poder crear una lista nueva y forzar algunos valores en la creación. En el caso de no indicar el resto de valores posibles, SharePoint utilizará los de por defecto.


Para comprobar que se ha creado, podremos navegar a la lista, o utilizar el botón que habíamos desarrollado antes para ver las listas del sitio actual. En este ejemplo yo ya llevaba creadas varias listas:


image


Añadir elementos a una lista genérica


Lo siguiente que vamos a hacer, es introducir elementos en las listas que creamos. Vamos a modificar la tabla donde se mostraba el listado de listas para añadir un botón de añadir elemento. Ahora el código Javascript de ese método sería el siguiente:


image


Antes de seguir, es importante entender, que para crear un elemento dentro de una lista, vamos a necesitar por supuesto el Id de la lista, y el EntityTimageype de la lista, para asegurarnos de que el elemento creado corresponde al que acepta nuestra lista. Ese valor, se puede consultar en los detalles de la lista, y se llama ListItemEntityTypeFullName. Estos dos valores se los vamos a pasar a la función que se encargará de añadir un elemento a una lista:


function addItemToList(listId, listItemEntityType) {
console.log("createBasicList");

var itemTitle = prompt("Enter item title");

if (itemTitle && itemTitle != '') {
var digest = getFormDigest();
if (digest && digest != '') {
var jsonBody = {
'__metadata': { 'type': listItemEntityType },
'Title': itemTitle
};
$.ajax({
url: "/_api/web/lists/getbyid('" + listId + "')/items",
type: "POST",
headers: {
"content-type": "application/json;odata=verbose",
"accept": "application/json; odata=verbose",
"X-RequestDigest": digest, "If-Match": "*"
},
data: JSON.stringify(jsonBody),
success: function (data) {
if (data.d) {
console.log("Item added");
alert("Item added");
}
},
error: function (xhr) {
console.error(xhr.status + ': ' + xhr.statusText);
}
});
}
}
}

Ahora en el body de la petición vamos a indicar este entity type, y el título del elemento a añadir. En la url vamos a indicar el id de la lista, e indicamos que vamos a atacar a los elementos de la lista. Para probar el código vamos a introducir un título para el elemento que añadamos, y veremos si el resultado a sido el deseado.


image


Podremos comprobar que el elemento se ha creado navegando a la lista y viendo los elementos que contiene.image


image


Actualización de una lista


Otra operación típica es la actualización de listas o elementos. En este caso vamos a introducir una descripción a la lista que seleccionemos del listado. Para ello vamos a modificar el método que lista las listas para añadir el botón que lance la operación:


image


Y el código para la actualización:


function setDescription(listId) {
console.log("setDescription");

var desc = prompt("Enter list description");
var digest = getFormDigest();

if (digest && digest != '') {
var jsonBody = {
'__metadata': { 'type': 'SP.List' },
'Description': desc
};
$.ajax({
url: "/_api/web/lists/getbyid('" + listId + "')",
type: "POST",
headers: {
"content-type": "application/json;odata=verbose",
"accept": "application/json; odata=verbose",
"X-Http-Method": "MERGE",
"X-RequestDigest": digest, "If-Match": "*"
},
data: JSON.stringify(jsonBody),
success: function () {
console.log("Description updated");
alert("Description updated");
},
error: function (xhr) {
console.error(xhr.status + ': ' + xhr.statusText);
}
});
}
}

En el body de la petición vamos a indicar la descripción, y en las cabeceras vamos a añadir el parámetro X-Http-Method: MERGE, para indicar que se trata de una actualización.


Podemos lanzar la prueba y ver el resultado:


image


Para comprobar que ha funcionado, podremos ver el detalle de la lista y comprobar que la descripción ha sido actualizada.


image


Eliminación de listas


En este caso vamos a añadir un botón al listado de listas para eliminar la lista seleccionada (cuidado de no eliminar ninguna lista que nos deje roto el sitio de SharePoint). El código para generar el listado quedaría así:


image


Y el código del método de borrado sería el siguiente:


function deleteList(listId) {
console.log("deleteList");

var c = confirm("Delete list?");
if (c == true) {
var digest = getFormDigest();

if (digest && digest != '') {
$.ajax({
url: "/_api/web/lists/getbyid('" + listId + "')",
type: "POST",
headers: {
"content-type": "application/json;odata=verbose",
"accept": "application/json; odata=verbose",
"X-Http-Method": "DELETE",
"X-RequestDigest": digest, "If-Match": "*"
},
success: function () {
console.log("List deleted");
alert("List deleted");
},
error: function (xhr) {
console.error(xhr.status + ': ' + xhr.statusText);
}
});
}
}
}

Aquí no tendremos que indicar ningún body en la petición, ya que se trata de un borrado. Lo que si debemos indicar es una cabecera de tipo X-Http-Method: DELETE. Probamos el código y vemos el resultado:


image


imageCon estos ejemplos básicos hemos podido comprobar cómo funcionan el conjunto de operaciones CRUD utilizando REST. Si queréis ampliar información os recomiendo echar un vistazo a la documentación del MSDN.


Espero que os haya sido de utilidad.

REST API en SharePoint 2013 I: Consulta básica sobre listas

SharePoint 2010 introdujo el “Client Object Models”, que permitía a los desarrolladores interactuar con el modelo de objetos a través de clientes Web, como Silverlight, Javascript y el modelo del lado cliente de .NET a través del servicio _vti_bin/client.svc.

En SharePoint 2013 el servicio client.svc se ha mejorado con capacidades REST (Representational State Transfer), soportando acceso directo a los clientes REST y haciendo más sencillo el acceso al mismo, o lo que es lo mismo, se podrá acceder al modelo de objetos haciendo uso de cualquier tecnología que sea compatible con las solicitudes REST.

Para usar estas capacidades REST habrá que construir peticiones RESTful utilizando el protocolo OData (Open Data Protocol), y el servicio client.svc entregará la respuesta en Atom o JSON, dejando que el programador se encargue de procesar dicha respuesta.

SharePoint REST service architecture

REST nos va a permitir realizar operaciones CRUD (Create, Read, Update y Delete) sobre los objetos SharePoint (listas, elementos de listas, sitios…). Típicamente las operaciones de lectura serán peticiones HTTP de tipo GET, mientras que las de creación y actualización serán de tipo POST, PUT, MERGE y PATCH.

En esta primera parte vamos a hacer un ejemplo sencillo del uso de peticiones de lectura sobre listas de SharePoint, que son las construcciones más sencillas, puesto que las que van a realizar modificaciones sobre objetos SharePoint requieren realizar una obtención de los que SharePoint denomina “Form Digest”, pero eso lo veremos más adelante.

Sintaxis de la estructura de una URI REST

En el siguiente esquema se muestra cómo es la sintaxis que se utiliza para construir URIs para atacar al servicio. Aunque en el ejemplo vamos a utilizar Javascript en un Webpart para mostrar los resultados, se puede también introducir la consulta directamente en la barra de direcciones del navegador y comprobar los datos que devuelve:SharePoint REST request syntax

Por ejemplo, para consultar las listas de la web actual, bastaría con escribir en nuestra barra de direcciones del navegador lo siguiente:

http://sp2013/_api/lists

Y en el navegador veríamos la respuesta del servicio.

Visto un breve resumen, vamos a comenzar con un ejemplo. Vamos a crear un Webpart muy sencillo, que contenga un botón que lance una petición REST para obtener todas las listas de la web actual y las muestre en una tabla. Para ello comenzamos un proyecto de tipo Visual Web Part.

image

image

Vamos a ayudarnos de jQuery para realizar las consultas imageAjax, por lo tanto debemos descargarlo y añadirlo a nuestra solución. También vamos a crear un script Javascript para escribir todo nuestro código. Organizarlo como más os guste, pero tened en cuenta luego los enlaces desde Webpart a la hora de hacer las referencias a los mismos.

En el código del control que forma parte del Webpart vamos a añadir las referencias a los dos scripts y además un botón que sea en que llame a nuestra función de Javascript, y una zona para insertar la tabla con los resultados. Podría tener esta pinta:

image

Vamos a comenzar con el Javascript. Creamos nuestra función encargada de hacer la llamada al servicio:

function getCurrentSiteLists() {
console.log("getCurrentSiteLists");

$.ajax({
url: "/_api/lists",
type: "GET",
headers: { "accept": "application/json; odata=verbose" },
dataType: "json",
success: onGetCurrentSiteListsSuccess,
error: function (xhr) {
console.error(xhr.status + ': ' + xhr.statusText);
}
});
}

Atended a los parámetros. Por un lado vamos a indicar la url a la que vamos a atacar, que en este caso es una url relativa a nuestro sitio, seguido de /_api/lists, ya que vamos a pedir las listas del sitio actual. Por otro lado el tipo de petición, es un tipo GET, y el tipo de dato que vamos a obtener es JSON. Además como cabecera de la petición es obligatorio indicar “accept”:”application/json; odata=verbose”. Sin este último parámetro no podemos realizar la petición, porque nos devolverá un error la respuesta.


Ahora vamos a construir la función que va a encargarse de recoger la respuesta y construir la tabla que vuelque los datos en pantalla:


function onGetCurrentSiteListsSuccess(data) {
console.log("onGetCurrentSiteListsSuccess");

if (data.d) {
var items = [];

items.push("<table>");
items.push("<tr><td>List ID</td><td>Title</td></tr>");

$.each(data.d.results, function (key, val) {
items.push("<tr><td>" +
val.Id + "</td><td>" +
val.Title + "</td><td></tr>");
});

items.push("</table>");
$("#RestResults").html(items.join(""));
}
}

Vamos a mostrar una tabla con el Guid de la lista y su título. El resultado de pulsar el botón sería similar al siguiente:


image


Hasta aquí es posible que nos hayamos encontrado con algunos problemas. Si es así revisad los parámetros de la consulta al servicio REST. Si aún así sigue habiendo problemas, revisad el log de SharePoint. imageYo por ejemplo, debido a limitaciones de máquina obtuve un error de memoria. El servicio me devolvió un Internal Server Error, y mirando en el log de SharePoint pude ver que se trataba de que la memoria escaseaba. El detalle del error era el siguiente:


Application error when access /_vti_bin/client.svc, Error=Memory gates checking failed because the free memory (180297728 bytes) is less than 5% of total memory. As a result, the service will not be available for incoming requests. To resolve this, either reduce the load on the machine or adjust the value of minFreeMemoryPercentageToActivateService on the serviceHostingEnvironment config element.

at System.ServiceModel.Activation.ServiceMemoryGates.Check(Int32 minFreeMemoryPercentage, Boolean throwOnLowMemory, UInt64& availableMemoryBytes)

at System.ServiceModel.ServiceHostingEnvironment.HostingManager.CheckMemoryCloseIdleServices(EventTraceActivity eventTraceActivity)

at System.ServiceModel.ServiceHostingEnvironment.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath, EventTraceActivity eventTraceActivity)

Y efectivamente, la memoria que quedaba libre era más bien poca.imageSolución, liberar memoria o asignar más a la máquina.




Una cosa que me ha gustado bastante del JSON devuelto ha sido que cuando queremos acceder a un atributo de un objeto que hemos pedido, y ese atributo es complejo, como por ejemplo, imagelos elementos que forman parte de la lista que estamos consultando, en el valor de ese atributo nos va a dar la url a la que tendríamos que atacar con REST para obtener dicha información. Esto se puede ver depurando el Javascript. Por ejemplo, obtenemos primero todas las listas del sitio en el objeto data.


Y depurando entramos en el detalle de cualquiera de las listas, y buscamos el atributo Items. Podremos ver que no salen directamente, y que en su lugar tenemos la url para realizar la siguiente consulta:


image


Por ejemplo, vamos a listar todos los atributos de la lista que seleccionemos. Para ello vamos a modificar el código Javascript, de tal forma que cuando hagamos clic en el Guid de la lista la tabla se alimente de esos valores. Vamos a consultar un atributo __metadata que tiene cada lista con la url a la que vamos a atacar con REST:


image


El atributo uri nos da la url que necesitamos, así que vamos a modificar cómo se presentan los datos de la primera consulta. Para ello, dentro del foreach vamos a construir un botón como el siguiente:


$.each(data.d.results, function (key, val) {
var metaUri = escape(val.__metadata.uri);
var linkDetails = "<button type='button' onclick=\"showListDetails('" + metaUri + "');\">" +
val.Id + "</button>";
items.push("<tr><td>" +
linkDetails + "</td><td>" +
val.Title + "</td><td></tr>");
});

Y creamos el código que lanzará la consulta REST:


function showListDetails(listUri) {
console.log("showListDetails");

$.ajax({
url: unescape(listUri),
type: "GET",
headers: { "accept": "application/json; odata=verbose" },
dataType: "json",
success: onShowListDetailsSuccess,
error: function (xhr) {
console.error(xhr.status + ': ' + xhr.statusText);
}
});
}

Y a continuación el código encargado de volcar los datos en la tabla:


function onShowListDetailsSuccess(data) {
console.log("onShowListDetailsSuccess");

if (data.d) {
var items = [];

items.push("<table>");
items.push("<tr><td>Attribute</td><td>Value</td></tr>");

$.each(data.d, function (key, val) {
items.push("<tr><td>" +
key + "</td><td>" +
val + "</td><td></tr>");
});

items.push("</table>");
$("#RestResults").html(items.join(""));
}
}

Así, cuando hagamos clic en el elemento de la lista, veremos todos los atributos junto con sus valores. El resultado sería similar al siguiente:


image


Como veis REST nos da la capacidad de realizar consultas del lado del cliente muy potentes, y podemos luego tratar y explotar los datos como nos convenga.


En esta caso hemos realizado sólo consultas de lectura. En el siguiente artículo veremos algún ejemplo de cómo realizar la creación de una lista y la diferencia que hay en la construcción de las peticiones REST.


Si queréis ampliar información, podéis hacer uso de los siguientes enlaces:


Programming using the SharePoint 2013 REST service


Using the SharePoint 2013 REST service

Novedades de características sociales en SharePoint Server 2013

imageEn cada nueva versión de SharePoint, se van introduciendo mejoras y nuevas características sociales, para mejorar la comunicación empresarial. En esta nueva versión nos vamos a encontrar con un MySite muy renovado que va a adaptar funcionalidades que nos recuerdan a Facebook y Twitter, y con dos nuevas plantillas de sitio para crear Comunidades, que van a proporcionar experiencias de foro y fomentar la comunicación y participación en el intercambio de información.

MySite

Al igual que en SharePoint 2010, en la versión de 2013 se siguen mantimageeniendo los sitios de usuario, con una nueva interfaz de usuario más moderna y limpia. Se siguen manteniendo conceptos como los de microblogging y discusiones, y aparecen otros nuevos como Newsfeed, menciones, etiquetas…, pero, realmente qué vamos a encontrarnos y qué aspecto tiene?

About Me

Una página en donde la gente va a poder saber acerca de nosotros. Proyectos en los que estamos trabajando, nuestras habilidades dentro de la empresa, formas de ponerse en contacto con nosotros y una lista con las actividades que estamos haciendo en SharePoint.image

Tendremos disponible además el gráfico organizativo de la empresa, imageen una vista dinámica con Silverlight. En la lista de actividades va a aparecer información reciente con las acciones que estamos realizando en la plataforma, ya sea realizar votaciones, comentarios, etiquetar contenido, etc.

Las etiquetas y notas realizadas pueden ser consultadas de forma global en una página, teniendo disponible una nube de etiquetas, que puede ser gestionada por el administrador de SharePoint, de tal forma que puede eliminar etiquetas que no considere apropiadas.

imageDe nuestro perfil podremos editar aquellos campos que estén habilitados para la edición (administrable de igual forma), y podremos elegir el nivel de visibilidad que van a tener para el resto de usuarios, pudiendo restringir la vista de cierta información a otros compañeros de la organización. Tendremos también la posibilidad de editar nuestra información para ser contactados por otros usuarios. Toda esta información tiene la posibilidad de ser incluida en los resultados de búsqueda de SharePoint, para facilitar la tarea de contactar con otros compañeros según sus habilidades u otros criterios.

Bibliotecas de documentos

Al igual que en la versión anterior, en SharePoint 2013 existe la posibilidad de tener bibliotecas privadas de documentos y bibliotecas públicas para compartir contenido con otros usuarios. En esta versión se han incluido mejoras de sincronización y compartición de esta información. Haciendo uso de Office 2013 tendremos la posibilidad de usar SkyDrive Pro, imageque nos va a permitir mantener sincronizada una biblioteca de documentos en nuestro disco local, teniendo acceso a los documentos de forma offline.

También podremos hacer seguimiento de documentos.image

Además el sistema de compartición se ha mejorado para que sea transparente para el usuario, facilitando la opción de compartir con diferentes usuarios olvidándonos de la gestión de permisos sobre documentos.

Newsfeed

En esta página podremos ver nuestro propio registro de actividades que estamos siguiendo, muy similar al tablón de usuario de Facebook. Este nuevo sistema nos va a permitir una vista mucho más dinámica que en la versión anterior, pudiendo iniciar y responder a conversaciones, incluir en dichas conversaciones enlaces e imágenes, compartir conversaciones, hacer menciones a otros usuarios usando el mismo sistema que Twitter (escribiendo el nombre de un usuario seguido del símbolo @), crear etiquetas usando primero el símbolo #, y teniendo la posibilidad de responder a una conversación con un “Me gusta”.

image

Además tendremos un acceso rápido al contenido que estamos siguiendo, como personas, documentos, sitios y etiquetas. Podremos acceder al detalle de cada categoría y la herramienta incluso nos sugerirá otro contenido que puede interesarnos seguir.image

Tareas

El concepto de tarea sigue siendo el mismo que en la versión anterior. imageLa novedad es que en esta versión tendremos la posibilidad de tener centralizadas todas las listas de tareas desde este enlace, cuando antes estaban localizadas en múltiples ubicaciones, lo que dificultaba el seguimiento. Tendremos la posibilidad de filtrar las tareas desde esta página.

Blog

Podremos crear un blog personal de la misma forma que en la versión anterior, pero ahora con la posibilidad de participar en conversaciones, hacer uso de etiquetas, responder con “Me gusta”, etc.image

Calificación o Rating de contenidos

Ahora con la nueva versión de SharePoint es posible de forma rápida realizar la calificación de contenidos en base a dos posibles criterios,image valorando de una a cinco estrellas un contenido, o mediante “Me gusta”. De esta forma SharePoint va a ser capaz de determinar la relevancia de un contenido, lo que se traduce a aparecer antes en un resultado de búsqueda. Para que sea posible utilizar esta característica habrá que activarla en las opciones de la lista o de la biblioteca de documentos en cuestión. Además esta calificación de contenidos va a formar parte de la actividad del usuario.

image

Comunidades

En SharePoint 2013 el concepto de comunidades consiste en un sitio que trata de ofrecer una experiencia de foro de discusión, un lugar en el que hacer y responder a preguntas, y mantener conversaciones de temas concretos. Las comunidades se pueden crear fácilmente por los departamentos de una organización, consiguiendo que los usuarios compartan su experiencia en áreas específicas de conocimiento.

Cuando dentro de una misma organización existen o conviven diferentes imagecomunidades es recomendable crear un portal de comunidades, que va a hacer la función de “portada” o página desde la cual va a ser posible acceder a las distintas comunidades que la forman, mediante una descripción de la misma y su icono.

Dentro de una comunidad se pueden crear categorías, de forma que resulte más cómodo el gestionar y localizar la información. Es una forma de organizar las conversaciones que tienen lugar en la comunidad.

imageAdemás cada comunidad incluye un buscador para poder realizar búsqueda de información dentro de la misma. De forma rápida se pueden acceder a las últimas conversaciones y ver los miembros pertenecientes.

 

 

La verdad es que en esta última versión se ha dado una gran importancia a la parte social y comunicativa de la plataforma, lo que la dota de una gran herramienta para fomentar la comunicación vertical y horizontal de una organización. Si queréis más información podéis consultar los siguientes en laces que son en los que me he basado para escribir este post.

Información general sobre las comunidades en SharePoint Server 2013

Novedades de los sistemas sociales en SharePoint Server 2013

Libro: Beginning SharePoint 2013: Building Business Solutions

SharePoint Between Racks © 2012
. Con la tecnología de Blogger.

¡Compártelo!


Estoy en LinkedIn!


Ve mi perfil en LinkedIn!