2009-04-20

Upload to Files to SharePoint using Microsoft.SharePoint

Recently, I posted an article on How to Post a File to a SharePoint Document Library using the SharePoint Web Services. I've also recently written some code that will allow you to do the same using the Microsoft.SharePoint Dll. Just a few words of advice... Any code that you write using Microsoft.SharePoint.dll needs to be running on a machine that has SharePoint installed on it. As far as I know, SharePoint 2003 or 2007 will work. This means that your development, testing, and product environments for this code must all run on a SharePoint Server. This maybe a deterrent for you to use Microsoft.SharePoint.dll, but if it's not, read on!

First, grab yourself a reference to the DLL in your VS.NET Project. Right click on your project, Add a Reference, and find the dll you need. Most likely it's located here:

C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI

Once you've added a Reference to Microsoft.SharePoint.dll, then you'll need to consume it. I've written the following class as a wrapper class to work with Document Libraries--It's far from complete, so you'll want to make sure that you write any additional functions that you may need.

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Microsoft.SharePoint;
using System.Collections;
using System.Diagnostics;

namespace SharePoint
{
    public class DocumentLibrary
    {
        public static void UploadFile(string DestinationUrl, byte[] FileContents, Hashtable Properties)
        {
            SPWeb site = new SPSite(DestinationUrl).OpenWeb();

            EnsureParentFolder(site, DestinationUrl);

            if (Properties == null)
            {
                Properties = new Hashtable();
            }

            // When running this code remotely, SharePoint complains that this is unsafe. To get around this,
            // Tell SharePoint that it's wrong.
            site.AllowUnsafeUpdates = true;
            // TODO: Reevaluate - Do we want to remove this if this code is running from the same server?

            site.Files.Add(DestinationUrl, FileContents, Properties, true);
        }

        public static string EnsureParentFolder(SPWeb parentSite, string destinUrl)
        {
            destinUrl = parentSite.GetFile(destinUrl).Url;

            int index = destinUrl.LastIndexOf("/");
            string parentFolderUrl = string.Empty;

            if (index > -1)
            {
                parentFolderUrl = destinUrl.Substring(0, index);

                SPFolder parentFolder = parentSite.GetFolder(parentFolderUrl);

                if (!parentFolder.Exists)
                {
                    SPFolder currentFolder = parentSite.RootFolder;

                    foreach (string folder in parentFolderUrl.Split('/'))
                    {
                        currentFolder = currentFolder.SubFolders.Add(folder);
                    }
                }
            }
            return parentFolderUrl;
        }

        public static FileVersionCollection ShowFileVersions(string FileUrl)
        {
            SPWeb site = new SPSite(FileUrl).OpenWeb();
            SPFile sp = site.GetFile(FileUrl);
            FileVersionCollection fvc = new FileVersionCollection();
            foreach (SPFileVersion spv in sp.Versions)
            {
                FileVersion fv = new FileVersion();
                fv.comments = spv.CheckInComment;
                fv.created = spv.Created;
                fv.createdBy = spv.CreatedBy.ToString();
                fv.size = spv.Size;
                fv.version = spv.VersionLabel;
                fv.url = spv.Url;
                fvc.Add(fv);
            }
            return fvc;
        }

        public static void DeleteFile(string FileUrl)
        {
            SPWeb site = new SPSite(FileUrl).OpenWeb();
            SPFile sp = site.GetFile(FileUrl);
            sp.Delete();           
        }
    }

    public class FileVersion
    {
       public FileVersion()
       {
       } 

       public string version
       {
           get;
           set;
       }
       public string url
       {
           get;
           set;
       }
       public DateTime created
       {
           get;
           set;
       }
       public string createdBy
       {
           get;
           set;
       }
       public long size
       {
           get;
           set;
       }
       public string comments
       {
           get;
           set;
       }
    }

    public class FileVersionCollection : List<FileVersion>
    {
    }


}

The extra classes are supplemental, and are not required for your integration with SharePoint. However, I found that they allow me to abstract the information from the other layers--I don't want my UI layer dealing directly with SharePoint's objects. Just my preference.

And if you missed it, I also included code similar to this, that allows you iterate through the different versions of a File stored in a Document Library. As usual, I hope this helps you out.

Zoidberg Away!

No comments: