En algunas ocasiones cuando extendemos SharePoint en nuestros desarrollos nos vemos con la necesidad de un implementar un servicio, ya vimos en un post anterior que opciones teniamos y los PROS y los contras. Si por la opción que hemos escogido es necesario que implementemos un WCF, una de las limitaciones que nos encontramos es que no podemos utilizar nuestros tipos personalizados.
Esto es un gran inconveniente, por muchos motivos:
- Nos obliga a introducir todas los propiedades de nuestro tipo por parámetros de la función. Esto puede provocar que en algunos casos superemos la longitud máxima de url y, por lo tanto, que se produzca un error en el servicio.
- Naturalmente, por la propia calidad del código ya que hay que hacer un procedimiento con muchos parámetros y no es una práctica muy buena.
¿Por qué no funciona?
Para que reconozca nuestros tipos personalizados hay que realizar diversas modificaciones en el WebConfig. Estas modificaciones se podrían llevar a cabo, pero puede tener efectos secundarios y estropear el funcionamiento interno de SharePoint. Por lo tanto, aunque sería posible solucionarlo, NO es recomendable. Es como matar moscas a cañonazos y podemos solventar este inconveniente de otra forma.
Ejemplo:
Vamos a realizar una llama a WCF que vamos a pasarle una clase Persona y nos devuelve si pertenece a un departamento de Administración.
La clase persona tiene las siguientes propiedades:
public class Persona { public int Id{ get; set; } public string Name{ get; set; } public string Apellidos{ get; set; } public string Departament{ get; set; } }
Una vez ya tenemos definida la clase, el siguiente paso es añadir el método en la interfaz del Servicio. Esta función tiene que ser invocada mediante un método POST. Además, el parámetro que tiene que tener esta función tiene que ser de tipo Stream.
Pero… ¿no queríamos pasar una clase Persona?
Sí, y es lo que vamos a pasar. En nuestro cliente, nosotros enviaremos en el Data un objeto de tipo Persona y en la propia definición de esta función, nos encargaremos de transformarla en un tipo Persona, como veremos a continuación.
El código de la interfaz sería el siguiente:
[OperationContract] [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "isDepartmentAdministration()" )] bool IsDepartmentAdministration(System.IO.Stream fileStream);
El código de la implementación del servicio sería el siguiente:
public bool IsDepartmentAdministration( System.IO.Stream fileStream) { var fs = StreamToString(fileStream); var request = Newtonsoft.Json.JsonConvert.DeserializeObject<Persona>>(fs); if (request.Deparment=="Administration") { return true; } else { return false; } }
De esta función, nos hemos creado la siguiente función que nos convierta un Stream en un String:
public static string StreamToString(System.IO.Stream stream) { using (System.IO.StreamReader reader = new System.IO.StreamReader(stream,System.Text.Encoding.UTF8)) { return reader.ReadToEnd(); } }
Una vez tenemos el string donde está la estructura es de un fichero json, queda convertirlo a nuestra clase. Para ello, hacemos uno de un paquete de Nuget llamado JSON.NET que se encarga de realizar la conversión de un string a la clase que le indicamos. Para más información sobre este proyecto se puede consultar la página de dicho proyecto: James Newton-King
Conclusión
SharePoint no es un producto sencillo, principalmente porque depende de muchos artefactos. Depende de IIS, de un SQL Server, de algunos desarrollos personalizados, de Timer Job… Todas estas dependencias provocan que algunos aspectos que puedan parecer muy simples no lo sean y éste es un claro ejemplo de ello. Pero, como muchas veces decimos, lo importante es que de una forma u otra podemos conseguir nuestro objetivo y de una forma adecuada.