Click here to Skip to main content
Click here to Skip to main content

Synchronize two SharePoint document workspaces

By , 6 Oct 2006
Rate this:
Please Sign up or sign in to vote.

Sample Screen shot

Introduction

This is my second code submission in CodeProject. Recently I was working with Microsoft SharePoint 2007 server and with its object models and the SharePoint web services as well. My intent was to make a program by which I can  move documents from one SharePoint document workspace to another. And to make the thing more applicable I was seeking a way where I can move documents back and forth between two different version of SharePoint server. And here in this article I have describe a way to transfer documents from a SharePoint 2003 server to a SharePoint 2007 server and vice versa.

Background

Windows SharePoint server offers a bunch (there are 16 and 5 additional services- so far I know) of web services for communicating with SharePoint. A list is given below

WSS Web Services

Web Reference

Administration Service

http:///_vti_adm/admin.asmx

Alerts Service

http:///_vti_bin/alerts.asmx>

Document Workspace Service

http:///_vti_bin/dws.asmx>

Forms Service

http:///_vti_bin/forms.asmx>

Imaging Service

http:///_vti_bin/imaging.asmx>

List Data Retrieval Service

http:// /_vti_bin/dspsts.asmx>

Lists Service

http:///_ vti_bin/lists.asmx>

Meetings Service

http:/// _vti_bin/meetings.asmx>

Permissions Service

http:// /_vti_bin/permissions.asmx>

Site Data Service

http:///_vti_bin/sitedata.asmx>

Site Service

http:///_vti_bin/sites.asmx>

Users and Groups Service

http:///_vti_bin/usergroup.asmx>

Versions Service

http:///_vti_bin/versions.asmx>

Views Service

http:///_vti_bin/views.asmx>

Web Part Pages Service

http:// /_vti_bin/webpartpages.asmx>

Webs Service

http:///_vti_bin/webs.asmx>

Using these web services one can achieve most of the features necessary to interact with SharePoint server. Of course one can write a custom web service also for his custom requirements. In fact I have written one. We will see that later in this article.

Beside this web services SharePoint Object model also exists. Which is an API defines some classes to interact with SharePoint service. But it is worth to notice that we can not use the SharePoint Object Model from a machine where the SharePoint service is not installed. These API can be used only from a machine where the SharePoint service is installed and running. If we want to use these API out side of the SharePoint server we have expose the API methods by creating a custom SharePoint web service.

So I had two ways to implement my objective. I could have implement two custom SharePoint web service, one for SharePoint 2003 and another for 2007. And from a client application I could reference those web services and could be able to move documents from one to another. But I have not implemented two custom web services. Because both web services will be exactly same except some configuration settings that will be appear for the different versions of SharePoint servers. Rather implementing two identical web services I have written one and that is for SharePoint 2003 server. In order to access and manipulate the SharePoint 2007 documents I have used the SharePoint object models directly. As you might be guessed already that, there is a short coming of this approach. we can not execute the application into a machine where the SharePoint 2007 is not installed. But this has done only for retaining the way of using object model directly. One can easily overcome this by implementing an identical web service like the one I have implemented for accessing the SharePoint 2003 server.

So, I am going to build a custom web service for SharePoint 2003 server that will expose some web methods for manipulation of the documents of a SharePoint 2003 document workspace. And after that I will create a simple windows application that will run into the machine where the SharePoint service 2007 is installed and running. From inside this windows application I will use SharePoint Object model APIs to interact with SharePoint 2007 server and consume the web service (that I have talked above) to interact with SharePoint 2003 server document workspace.

Using the code

Creating the Web service for SharePoint 2003

First of all I need to create a custom SharePoint web service for my SharePoint 2003 server. There is a cool MSDN article that explains how to write custom SharePoint web services. So first of all create a simple web service project named "Document03Service". I have created this web service using VS.NET 2003. So I have got an assembly as an output of my web service project. Those who are using ASP.NET 2.0 web services may need to build their assembly by using the Web Deployment project.

First of all remove the Service1.asmx file and attach a new class file named DocService. Now you have to add a reference of Microsoft.SharePoint.dll to the web service project. The assembly can be found at "%COMMONPROGRAMFILES%\Microsoft Shared\Web Server Extensions\60\ISAPI". for example I have got it into "C:\Program Files\Common Files\Microsoft Shared\web server extensions\60\ISAPI\Microsoft.SharePoint.dll" into the machine where SharePoint 2003 installed.

Now, add the following lines into the top of the DocService class.

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;

  Now you need to add a web method that will be used to upload a new document to the SharePoint Document workspace. 

[WebMethod]
public string UploadDocument(string fileName, 
       byte[] fileContents, string folderPath)
{
    if ( fileContents == null)
    {
        return "The document sent is not a valid" + 
               " document. It is either empty or zero";
    }
    try
    {
        // get the site reference from the context
        SPWeb site = SPControl.GetContextWeb(Context);
        // get the folder
        SPFolder folder = site.GetFolder(folderPath);
        string fileUrl = fileName;
        // attach the file now 
        SPFile file = folder.Files.Add(fileUrl, fileContents);
        // return the message
        return file.TimeCreated.ToLongDateString()+ "::" + file.Title;
    }
    catch (System.Exception ee)
    {
        return ee.Message + "::" + ee.Source;
    }
}

The method takes three arguments. The first one is the file name that will be uploaded, second one is an array of byte that contains the binary representation of the document content and the final argument is the name of the document library folder beneath which we are going to upload the file. First of all the reference of the SharePoint web has retrieved by using the static GetContextWeb method of the SPControl class. and then from the web reference we are extracting a reference of the document folder by using the method GetFolder. And finally, we are attaching a new file to file collection of the document folder.

Let's now create some more web methods to this class.

// Downloads a document   
[WebMethod()]
public byte[] DownloadDocument( string fileUrl , string folderPath )
{
    Byte[] content = null;

    if( null == fileUrl || fileUrl.Length <= 0 )
        throw new ArgumentException("Invalid file url.");

    try
    {
        // get the web
        SPWeb web = SPControl.GetContextWeb( Context );
        // get the folder path
        SPFolder folder = web.GetFolder( folderPath );
        
        foreach( SPFile file in folder.Files )
        {    // Iterate thru the files
            if( file.Url == fileUrl )
            {    // If this is the file we are looking for
                content = new byte[file.Length];
                file.SaveBinary( content );    // save the file now
            }
        }
    }
    catch(Exception ex)
    {
        throw new Exception( "Error while processing..", ex);
    }
    return content;
}

// Get the list of available file's url for a given folder path
[WebMethod()]
public string[] GetFileUrls( string folderPath )
{
    ArrayList list = new ArrayList();

    if( null == folderPath || folderPath.Length <= 0 )
        throw new ArgumentException("Invalid folder path.");

    try
    {
        // get the web
        SPWeb web = SPControl.GetContextWeb( Context );
        // get the folder path
        SPFolder folder = web.GetFolder( folderPath );
        
        foreach( SPFile file in folder.Files )
        {    // Iterate thru the files
            list.Add( file.Url );
        }
    }
    catch(Exception ex)
    {
        throw new Exception( "Error while processing..", ex);
    }
    return list.ToArray(typeof(string)) as string[];
}

Now build the web service. Now we have to generate the DISCO and WSDL files for the web service.

Creating the DISCO and WSDL file

Go to the .NET command shell and execute the .NET DISCO generation utility program for this web service. Into the command prompt write

DISCO http://localhost/Document03Service/DocService.asmx

and press return key. This command will generate the DISCO and WSDL files into the current directory.

Now open the DocService.disco file and locate the following line

<?xml version="1.0" encoding="utf-8"?>

Replace the preceding line with the following lines:

<%@ Page Language="C#" Inherits="System.Web.UI.Page"%>
<%@ Assembly Name="Microsoft.SharePoint, Microsoft.SharePoint, 
       Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint.Utilities" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<% Response.ContentType = "text/xml"; %>

Now rename the file as DocServicedisco.aspx. Perform the same task for the DocService.Wsdl and rename that DocServicewsdl.aspx.

To modify the DocServicedisco.aspx file and the DocServicewsdl.aspx file to support service virtualization

Note   The following code examples, and subsequent ones, include extra line breaks to facilitate online display. To use these examples, please remove the extra line breaks.
  1. Open the DocServicedisco.aspx file, and then locate the following tag:
    <contractRef ref="http://server_name:New_Port/
                      Document03Service/DocService.asmx?wsdl" docRef=
    "http://server_name:New_Port/Document03Service
          /DocService.asmx" 
          xmlns="http://schemas.xmlsoap.org/disco/scl/" />
  2. Make the following changes in the <contractRef> tag:
    <contractRef ref=<% SPEncode.WriteHtmlEncodeWithQuote(Response, 
       SPWeb.OriginalBaseUrl(Request) + "?wsdl", '"'); %> 
    docRef=<% SPEncode.WriteHtmlEncodeWithQuote(Response,
            SPWeb.OriginalBaseUrl(Request), '"');
    %> xmlns="http://schemas.xmlsoap.org/disco/scl/" />
  3. Locate the following tag:
    <soap address="http://server_name:New_Port/
                  Document03Service/DocService.asmx"
                  xmlns:q1= "http://tempuri.org/" binding="q1:DocServiceSoap"
                  xmlns="http://schemas.xmlsoap.org/disco/soap/" />
  4. Change the <soap address> tag as follows, and then save the changes:
    <soap address=<% SPEncode.WriteHtmlEncodeWithQuote(Response, 
                     SPWeb.OriginalBaseUrl(Request), '"'); %>
    xmlns:q1="http://tempuri.org/" binding="q1:Service1Soap"
    xmlns= "http://schemas.xmlsoap.org/disco/soap/" />
  5. Open the DocServicewsdl.aspx file, and then locate the following line:
    <soap:address location="http://server_name:
                  New_Port/Document03Service/DocService.asmx" />
    
  6. Make the following changes to the soap:address line, and then save the changes:
    <soap:address location=<% SPEncode.WriteHtmlEncodeWithQuote(Response,
     SPWeb.OriginalBaseUrl(Request), '"'); %> />
    

To copy the Web service files to the _vti_bin virtual directory

  1. Copy the DocServicewsdl.aspx file, the DocServicedisco.aspx file, and the DocService.asmx file to the _vti_bin virtual directory. This is the directory where all default Web services are stored.
  2. Copy the corresponding assembly (DLL) (Document03Service.dll, for our project) file to the _vti_bin/bin virtual directory.
    Note   The _vti_bin/bin virtual directory is mapped to the \\<Server_Name>\Program Files\Common  Files\Microsoft Shared\Web Server Extensions\ISAPI directory.

Next, you must include the service in the list of default Windows SharePoint Services Web services that is displayed in the Add Web Reference browser of Visual Studio .NET.

To include the Web service in the list of Web services on the server

  1. In Notepad, open the spdisco.aspx file of the Local_Drive:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\60\ISAPI folder.
  2. Add the following lines to the end of the file within the discovery element and save the file:
    <contractRef ref=<% SPEncode.WriteHtmlEncodeWithQuote(Response, 
            spWeb.Url + "/_vti_bin/DocService.asmx?wsdl", '"'); %>
    docRef=<% SPEncode.WriteHtmlEncodeWithQuote(Response, 
           spWeb.Url + "/_vti_bin/DocService.asmx", '"');%>
    xmlns="http://schemas.xmlsoap.org/disco/scl/" />
    <soap address=<%SPEncode.WriteHtmlEncodeWithQuote(Response, 
              spWeb.Url + "/_vti_bin/Service1.asmx", '"'); %>
    xmlns:q1="http://schemas.microsoft.com/sharepoint/
              soap/directory/" binding="q1:DocServiceSoap"
    xmlns="http://schemas.xmlsoap.org/disco/soap/" />
    Note The text appearing before "Soap" in the binding attribute of the soap element (in this example, binding="q1:DocServiceSoap") specifies the name of the class that is defined in the Web service.

Now you can test the web service from your browser that if the web service is successfully deployed. Point your browser to: http://localhost/_vti_bin/DocService.asmx, and watch if it displays the web methods.

Now I am going to build the windows application that will run into the machine where the SharePoint server 2007 is installed and running.

Building the Windows based client application

Open the VS.NET 2005 and create a new windows application named SampleClient. Add a reference of the web service that we have created just before a while. As this application will interact with SharePoint 2007 we have to add another reference of Microsoft.SharePoint.dll. it is worth to remember that we have to refer this dll from the machine where SharePoint 2007 is installed. Because this application need this assembly version 12.0.0.0 which ships along with SharePoint 2007 server installation.  

Note   Previous section we have used version 11.0.0.0 of this assembly. Which is compatible with SharePoint 2003 server

Now rename the Form1.cs file to DocumentSynch.cs. And instead of designing the GUI from the scratch please copy the code that I have enclosed along with this article in zip format. After copying you can build the project. If the build process completed then you can launch the application executable to move documents from one SharePoint server to another.

Points of Interest

While I was working this topic I was found some more interesting thing regarding Windows Workflow integration with Windows SharePoint services. In my next article I will demonstrate some work on that topic.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Moim Hossain
Software Developer (Senior) BlueCielo ECM Solutions
Netherlands Netherlands
Jack of all trades....
Follow on   Twitter

Comments and Discussions

 
GeneralCannot transfer file Pinmemberjub77devil20-Aug-09 16:00 
GeneralCannot find Microsoft.SharePoint.dll or one of the dependencies Pinmemberjub77devil19-Aug-09 23:29 
GeneralRe: Cannot find Microsoft.SharePoint.dll or one of the dependencies PinmemberMoim Hossain19-Aug-09 23:33 
GeneralRe: Cannot find Microsoft.SharePoint.dll or one of the dependencies [modified] Pinmemberjub77devil20-Aug-09 15:04 
GeneralRe: Cannot find Microsoft.SharePoint.dll or one of the dependencies Pinmemberjub77devil20-Aug-09 15:47 
GeneralConverting list PinmemberHossein eraghi8-Dec-08 2:06 
GeneralFile Not Found. Error when browsing to service on 2003 site Pinmembermgarner135126-Jun-08 9:59 
QuestionDoes this transfer metadata like vti_timelastmodified? Pinmembermbaltaks14-Feb-08 17:17 
QuestionAbove code not working properly..Please help Pinmembersatishsashi24-Jul-07 1:53 
GeneralRe: Above code not working properly..Please help PinmemberMoim Hossain16-Jan-08 4:41 
QuestionVersion info? PinmemberInsane D1-May-07 23:13 
AnswerRe: Version info? PinmemberMoim Hossain23-Jun-07 20:18 
QuestionDocument Properties PinmemberAPAM9-Apr-07 6:45 
AnswerRe: Document Properties PinmemberMoim Hossain23-Jun-07 20:19 
GeneralRe: Document Properties PinmemberAPAM24-Jun-07 5:55 
GeneralRe: Document Properties PinmemberMoim Hossain24-Jun-07 17:50 
GeneralRe: Document Properties Pinmembershob_sp27-Nov-08 18:23 
GeneralFound a bug ;-) PinmemberEd.Richard4-Dec-06 16:28 
GeneralRe: Found a bug ;-) PinmemberMoim Hossain23-Jun-07 20:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140421.2 | Last Updated 6 Oct 2006
Article Copyright 2006 by Moim Hossain
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid