Subir achivos a Sharepoint desde un programa en un equipo remoto

Me pedía el otro día un amigo una función para subir archivos a una librería de documentos de Sharepoint desde un equipo remoto. Yo, aunque no lo habia hecho nunca, pense que seria una tarea sencilla de realizar usando los servicios Web expuestos por Sharpoint. Tras un rato de investigación descubrí que no hay ningun servicio Web de Sharepoint que permita hacer esto de manera directa.

Tras un poco más de información encontre un solución sencilla, basada en hacer una llamada PUT al servidor de Sharepoint. Podeís ver a continuación un código de ejemplo de esta solución.

    /// <summary>

    /// Función que sube un archivo a un servidor Sharepoint remoto

    /// usando una petición PUT.

    /// </summary>

    /// <param name="localFile">Path del archivo local</param>

    /// <param name="remoteFile">Url del archivo remoto</param>

    /// <remarks>

    /// Esta función sirve desde la versión 1.0 del Framework en adelante

    /// </remarks>

    public void UploadDocument(string localFile, string remoteFile)

    {

      // Leer el archivo local

      FileStream fs = new FileStream(localFile, FileMode.Open, FileAccess.Read);

      byte[] buffer = new byte[fs.Length];

      fs.Read(buffer, 0, Convert.ToInt32(fs.Length));

      fs.Close();

 

      // Creamos el objeto request para lanzar la petición

      WebRequest wr = WebRequest.Create(remoteFile);

      wr.Credentials = System.Net.CredentialCache.DefaultCredentials;

      wr.Method = "PUT";

      wr.ContentLength = buffer.Length;

 

      // Escribimos el archivo en sitio remoto

      BinaryWriter bw = new BinaryWriter(wr.GetRequestStream());

      bw.Write(buffer, 0, buffer.Length);

      bw.Close();

 

      // Obtener el resultado de la petción

      HttpWebResponse wres = (HttpWebResponse)wr.GetResponse();

      wres.Close();

    }

El código anterior funciona perfectamente, pero tiene dos pegas, si subimos el archivo así no se guarda el historial de versiones y la petición es síncrona, lo que puede ser un problema para subir muchos archivos o archivos grandes. La primera es inevitable usando el método de hacer PUT, la segunda, si utilizamos el Framework 2.0 de .Net es simple de solucionar. Podemos utilizar las funciones asíncronas de la clase WebClient para subir el archivo. Tambien, podriamos hacerlo en .Net 1.x, pero tendríamos que usar hilos . Aquí va un pequeño ejemplo de código de como subir un archivo asíncronamente.

    /// <summary>

    /// Función que sube un archivo a un servidor Sharepoint remoto,

    /// de manera asíncrona, usando una petición PUT.

    /// </summary>

    /// <param name="localFile">Path del archivo local</param>

    /// <param name="remoteFile">Url del archivo remoto</param>

    /// <remarks>

    /// Esta función sirve desde la versión 2.0 del Framework en adelante,

    /// no funciona en 1.0, ni en 1.1

    /// </remarks>

    public void UploadDocumentAsync(string localFile, string remoteFile)

    {

      // Leemos el archivo

      FileStream fs = new FileStream(localFile, FileMode.Open, FileAccess.Read);

      byte[] buffer = new byte[fs.Length];

      fs.Read(buffer, 0, Convert.ToInt32(fs .Length));

      fs.Close();

 

      //Subimos el archivo de manera asíncrona

      WebClient wc = new WebClient();

      wc.Credentials = System.Net.CredentialCache.DefaultCredentials;

 

      //Manejador de evento para obtener información sobre el progreso

      wc.UploadProgressChanged += new UploadProgressChangedEventHandler(UploadProgressChanged);

      //Manejador de evento para saber cuando se completo la subida del archivo

      wc.UploadDataCompleted += new UploadDataCompletedEventHandler(UploadDataCompleted);

      //Iniciamos la subida del archivo asincronamente

      wc.UploadDataAsync(new Uri(remoteFile), "PUT", buffer);

      //Podriamos cancelar la carga del archivo

      //wc.CancelAsync();

    }

 

    /// <summary>

    /// Manejador de evento que recibe información sobre

    /// el progreso de la carga asíncrona del fichero.

    /// </summary>

    void UploadProgressChanged(object sender, UploadProgressChangedEventArgs e)

    {

      String msg = string.Format("Progreso: {0}%", e.ProgressPercentage);

      Trace.WriteLine(msg);

    }

 

    /// <summary>

    /// Manejador de evento que recibe información sobre

    /// el resultado de la operación de carga del fichero

    /// cuando esa se completa

    /// </summary>

    void UploadDataCompleted(object sender, UploadDataCompletedEventArgs e)

    {

      if (e.Cancelled == true)

        Trace.WriteLine("Se cancelo la operación");

      else if (e.Error != null)

      {

        String msg =

          string.Format(

          "Se produjo una excepción durante la operación: {0}",

          e.Error.ToString());

        Trace.WriteLine(msg);

      }

    }

Pero que pasa si no podemos vivir sin el historial. Pues existe un tercer cámino, bastante más complejo, que es crear un Web Service e integrarlo en el API de Sharepoint. La solución no es tan sencilla de realizar como las anteriores, pero esta perfectamente explicada en este artículo. Además, alguien ya implemento este web service y lo compartio con la comunidad, podeís descargarlo, desde GotDotNet

Seguro que alguno de los lectores de mi blog incluso sugiere alguna otra via…

4 comentarios sobre “Subir achivos a Sharepoint desde un programa en un equipo remoto”

  1. Pese a que hace mucho del ejemplo mostrado, me animaré a aportar algo sobre el tema dado que en la empresa en la que estoy trabajando estamos en plena implantación de SP2007 y subir un fichero programaticamente ha sido una de las primeras funcionalidades que hemos requerido de SP.

    Al igual que tú, asumí que tenía que existir un WS que facilitase la subida de un fichero a SP de forma «maravillosamente fácil». De hecho, la pregunta al consultor implantardor se realizó pero se nos perdió en un mar de excusas e incertidumbres. Investigamos un poco y no encontramos nada de forma directa, sin embargo profundizando un poco más encontramos una forma sencilla de realizar la subida de un fichero a SP. Esta simplemente consistía en mapear una unidad de disco a una url de SP (haciendo uso de WebDAV y WebFolders) lo que permitía hacer uso de SP como un servidor de ficheros más.

    Si bien es cierto que esta solución nos permitió salvar los muebles dada la premura que se tenía en la obtención de la funcionalidad, eso de andar mapeando unidades en un servidor donde publicamos un WS propio y demás no nos acababa de convencer.

    La otra alternativa que se encontro y que nos gustó un poco más fue hacer uso de WebDAV programáticamente. Aquí tenéis un ejemplo http://www.thescripts.com/forum/thread356985.html y aquí otro http://www.walisystems.com/articles/SPS/SPSFileUpload.asp aunque no difieren mucho de lo indicado por tí.

    No profundizamos en el tema, pero pare tener control de versiones existe un API (DeltaV) que si SP la soporta, permitiría la gestión de las versiones.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *