martes, 21 de abril de 2009

Cantidad de Visitas al Articulo:

Sharepoint – Usando sus Web Services

LogoMOSS_50Dado un proyecto en el que estoy involucrado directamente, he tenido que meterme fuerte en el uso de Sharepoint 2007 (MOSS) para utilizarlo como repositorio de documentos desde un sistema externo.

Aquí comparto con Uds. algunos detalles importantes que me toco investigar, con los típicos “detalles” que terminan haciéndote pasar momentos difíciles.

Si bien aquí desarrollo algo muy básico, les aseguro que si necesitan desarrollar algo del estilo, este artículo les servirá, porque en definitiva, recopila información recogida a lo largo de varias horas de navegación en la web, y luego de probarlo en un ambiente real.

Es factible probar todo esto contra una máquina virtual con Windows 2003 Server Trial y Sharepoint 2007 Trial, que tiene una duración de 60 días, y se pueden descargar desde Microsoft Download Center..

El Contexto

Lo primero que hay que aclarar es que Sharepoint es una herramienta mucho mas amplia que un simple repositorio de documentos. Como explica el link al site de MOSS, este producto permite la colaboración entre equipos, compartiendo información fácil y rápidamente, incluso definiendo workflow a los documentos, lo que lo hace muy potente.

Es factible definir colecciones de sitios web, desde plantillas predefinidas,  permitiendo luego que cada usuario personalice su propio sitio, e incluso configure los permisos de acceso a su espacio de trabajo. Todos los permisos están relacionados directamente al AD de Windows.

Como todo repositorio, es factible alojar documentos de diversos tipos,DiagramaMOSS como office, pdf, musicales, videos, imágenes, etc.

Se pueden definir cotas de espacio por sites, por tipos de documentos, e incluso por base de datos, utilizadas para el almacenamiento. Esto permite, desde el punto de vista administrativo, tener un control en el uso de espacio, dado que los usuarios solemos desestimar ese tema, hasta que nos quedamos sin espacio para trabajar. Cada site puede tener asociada una base de datos, o compartirla con otras. Esto queda a criterio del administrador del sistema, pero normalmente se opta por separar las bases de datos, para acelerar los procesos de recuperación en caso de ser necesario, y para tener mas control por aplicación de negocios o espacios específicos de colaboración. Lo importante, es que TODO se almacena en base de datos SQL Server, y no se usa filesystem para nada. Podría se factible desarrollar un provider para almacenamiento en otro repositorio, pero habría que analizar bien la necesidad para justificar en ese caso, la pérdida de seguridad y eventualmente falta de integridad, características que son nativas de MOSS cuando se utiliza SQL Server.

Para trabajar con MOSS, es factible hacerlo de 3 formas:

  1. A través de su interface (Web), accediendo al sitio en que tenemos permisos, y utilizando las opciones habilitadas según nuestro perfil.
  2. A través de la API MOSS, pero SOLO si estamos en la misma máquina donde está instalado el producto.
  3. A través de Web Services estándares de MOSS, que se publican en cada uno de los sites que se crean, sea principal o secundario, y que permiten hacer casi la totalidad de las operaciones que se pueden hacer desde la interface web standard. En caso de existir alguna operación que no se pueda hacer con estos web services, se desarrolla uno nuevo con la API MOSS, se la publica en el sitio que se necesita, y se lo consume tal cual los web services estándares.

Nuestro Ejemplo

Mas allá de las pocas características antes enumeradas, lo que utilizamos en nuestro proyecto fue solo la capacidad de almacenamiento y versionamiento de documentos, en lo que MOSS denomina Document Libraries (Biblioteca de Documentos). Básicamente una DL es un espacio físico que almacena documentos de cualquier tipo, dentro de la estructura de directorios que definamos.

Aquí comienzan a aparecer los problemas típicos de tamaños, espacios, etc. Una limitante que tiene MOSS 2007, cuando utilizamos SQL Server 2005, es que podemos almacenar documentos menores a 2Gb. Esto es porque la limitante se hereda del SQL Server 2005, donde es imposible almacenar una fila mas grande que ese tamaño. No es el caso del SQL Server 2008, que no tiene cota máxima.

De todas formas, el tamaño de los documentos, no es solo por las cotas, sino por la congestión de la red, en caso que sean demasiado grandes y/o que las conexiones sean algo lentas.

Ok Según recomendaciones de Microsoft, es mejor no sobrepasar ciertos límites de cantidades de documentos por carpetas, para evitar problemas en el uso de la interface web. Cuando trabajamos como en nuestro caso programáticamente, pero sin usar la interface nativa, ese límite es mas flexible.

Un tema importante que mencione al pasar antes, es el versionamiento automático que se puede definir en las DL, para que cada vez que subamos un documento, MOSS se encargue de éste tema. Luego es factible recuperar la lista de versiones así como los documentos correspondientes a cada una.

Acerca de la lista de web services estándares, no haré demasiados comentarios, porque aquí pueden encontrar mucha información al respecto, así como en web. Luego, es mucho de prueba y error, para ver como se comportan cada uno de ellos. Es importante aclarar que no todos tienen el mismo tipo de salida, es decir, el resultado retornado no es siempre del mismo tipo, lo que hace mas dificultoso la programación, pero luego de un poco de pruebas, se generalizan las operaciones mas importantes.

Algunos Tips importantes para la programación

Si deseamos hacer un upload de un documento programáticamente a través de los web services estándares de MOSS, podemos hacer algo del estilo:

using (Copy ws = new Copy())
{
    try
    {
        ws.Timeout = _Timeout;
        ws.Credentials = _Credential;

        string[] copyDest = { <URL de MOSS> };

        FieldInformation myFieldInfo1 = new FieldInformation();
        myFieldInfo1.InternalName = "Title"; //Titulo
        myFieldInfo1.DisplayName = "Título"; //Titulo
        myFieldInfo1.Type = FieldType.Text;
        myFieldInfo1.Value = filename;

        FieldInformation[] myFieldInfoArray = { myFieldInfo1 };

        CopyResult myCopyResult1 = new CopyResult();
        CopyResult[] myCopyResultArray = { myCopyResult1 };

        //Hago el upload propiamente dicho
        uint myCopyUint = ws.CopyIntoItems("
http://null", copyDest,myFieldInfoArray, file, out myCopyResultArray);
        if (myCopyUint == 0)
        {
            if (myCopyResultArray[0].ErrorMessage != null)
            {
                log.Error("MOSSHelper.UploadDocument [ErrorCode=" + myCopyResultArray[0].ErrorCode + " -  ErrorMessage=" + myCopyResultArray[0].ErrorMessage + "]");
             return ParseErrorCopy(myCopyResultArray[0].ErrorCode);
            }

}

Copy hace referencia al WS Copy.asmx.

Nota Importnate: Tengan especial cuidado cuando utilicen FieldInformation, para agregar un metadato asociado al documento, dado Lupa que si no se completan tanto el Inernal como el DisplayName, ademas del Type y el Value, se completa el upload pero no se llena ese metadata. Y si despues se necesita ese metadata para efecutar búsquedas, estarás en problemas. Además, dependiendo de la versión (inglés, español, etc) el InternalName cambia, y ocurre lo mismo que si no se llenara.

Un Download del mismo archivo podría ser:

using (Copy ws = new Copy())
{
    try
    {
        ws.Timeout = _Timeout;
        ws.Credentials = _Credential;

        string urlSource = <URL total del docuemnto en MOSS>;

        FieldInformation[] myFieldInfoArray;
        CopyResult myCopyResult1 = new CopyResult();
        //Hago el download propiamente dicho
        uint myCopyUint = ws.GetItem(urlSource, out myFieldInfoArray, out file);
        if (myCopyUint != 0)
        {
            ret = (int)myCopyUint;
        }
        else if (file == null)
        {
            ret = RET_ERR_DOCUMENT_NOT_FOUNT_IN_MOSS;
        }
    }   

}

Crear un DL:

using (Lists ws = new Lists())
{
    try
    {
        ws.Timeout = _Timeout;
        ws.Credentials = _Credential;
        string strResult = "";
        System.Xml.XmlNode nodeListItems = ws.AddList(nameDL, descripcionDL, 101);
        ret = ParseErrorCreateDL(nodeListItems);

    }    }

Aquí usamos el WS Lists.asmx.

Utilizando DWS.asmx, es factible crear carpetas, con CreateFolder.

Por último, con Versions.asmx, se pueden recuperar las versiones de un documento, y luego, a través de su URL completa, y con ayuda nuevamente de Copy, se pueden recuperar.

Espero les sirvan estos comentarios, y cualquier duda me avisan, para ver si puedo ayudarlos, y de paso, sigo aprendiendo.

So far, So good!

 

Cantidad de Visitas al Articulo:

3 comentarios:

Martin dijo...

Hola Gustavo,

Me ha resultado sumamente útil tu post ya que justamente el requerimiento que estoy manejando es el de permitir que un sistema externo explore una biblioteca de documentos en MOSS.

Lo específico de mi caso es que además se requiere llegar a las posibles versiones del mismo, por lo que Versions.asmx me fue de mucha utilidad.

El tema es que esta biblioteca tiene metadata por lo que me surgen 2 preguntas:

1. La metadata también se versiona?

2. De ser SI la respuesta anterior, cómo accedo a esa información?? Yo esperaría obtener un DOM similar al que obtengo del XML de la lista, pero sólo me arroja unos atributos como versión, URL, creación.

Es posible instanciar una determinada versión y obtener la metadata de la misma? (otra vez, si es que la metadata se versiona)

Mil gracias desde ya.

Martín.-

Gustavo Suhit dijo...

Martín,
Dado que nunca tuve ese problema, jamás me lo cuestioné. :-(
Lamento no poder ayudarte.
Solo por sensación de estómago se me ocurre que como la metadata en realidad es información para identificar el documento, ésta siempre debería estar actualizada, y no se deberían generar versiones. Si necesitaras mantener la historia de las modificaciones, quizá deberías tener una metadata variable, o algún campo de multitexto, donde vayas agregando las modificaciones realizadas. Pero de nuevo, es solo sensación, nada que te pueda confirmar.
Si encuentro alguna información adicional que te pueda ayudar te aviso.
Saludos, Gustavo.

Unknown dijo...

hola gustavo, yo necesitaria hacer mas o menos lo mismo que has comentado pero en vb.net y el problema viene en k no se nada de sintaxis de CSharp, si pudieras ponerlo en vb.net si saves o empaquetarlo o algo parecido! es que me resultaria de gran utilidad tu post! realmente es muy claro con el tema de las referencias web. me ha alludado un poco mas a la comprension!


gracias

 
Este Weblog, InforMateando..., está licenciado bajo Licencia Creative Common - por Gustavo Suhit