31

What is the best way to upload a file to a Document Library on a SharePoint server through the built-in web services that version WSS 3.0 exposes?

Following the two initial answers...

  • We definitely need to use the Web Service layer as we will be making these calls from remote client applications.

  • The WebDAV method would work for us, but we would prefer to be consistent with the web service integration method.

There is additionally a web service to upload files, painful but works all the time.

Are you referring to the “Copy” service? We have been successful with this service’s CopyIntoItems method. Would this be the recommended way to upload a file to Document Libraries using only the WSS web service API?

I have posted our code as a suggested answer.

Andy McCluggage
  • 37,618
  • 18
  • 59
  • 69

7 Answers7

17

Example of using the WSS "Copy" Web service to upload a document to a library...

public static void UploadFile2007(string destinationUrl, byte[] fileData)
{
    // List of desination Urls, Just one in this example.
    string[] destinationUrls = { Uri.EscapeUriString(destinationUrl) };

    // Empty Field Information. This can be populated but not for this example.
    SharePoint2007CopyService.FieldInformation information = new 
        SharePoint2007CopyService.FieldInformation();
    SharePoint2007CopyService.FieldInformation[] info = { information };

    // To receive the result Xml.
    SharePoint2007CopyService.CopyResult[] result;

    // Create the Copy web service instance configured from the web.config file.
    SharePoint2007CopyService.CopySoapClient
    CopyService2007 = new CopySoapClient("CopySoap");
    CopyService2007.ClientCredentials.Windows.ClientCredential = 
        CredentialCache.DefaultNetworkCredentials;
    CopyService2007.ClientCredentials.Windows.AllowedImpersonationLevel = 
        System.Security.Principal.TokenImpersonationLevel.Delegation;

    CopyService2007.CopyIntoItems(destinationUrl, destinationUrls, info, fileData, out result);

    if (result[0].ErrorCode != SharePoint2007CopyService.CopyErrorCode.Success)
    {
        // ...
    }
}
Ocelot20
  • 10,510
  • 11
  • 55
  • 96
Andy McCluggage
  • 37,618
  • 18
  • 59
  • 69
  • Have you found any issues with errors when the file already exists? I started using this technique but found I constantly received an error "Cannot create an item at the requested destination. Verify that the folder exists and that you have permission to edit in it". Anyone else had this problem? – misteraidan Jul 01 '09 at 00:05
  • 1
    UPDATE -- if destinationUrl is the same as the url inside destinationUrls[], the error above is thrown if the file/item already exists .... (rant: why can't we edit comments?!) – misteraidan Jul 01 '09 at 00:15
  • No, I never had any such problems. It's your classic "bad destination" error, but if you are sure the destination is correct and that you have permission, I can't think what else could be causing this. – Andy McCluggage Jul 04 '09 at 13:45
  • 2
    Can you expand this to show how to call this? In particular what the destinationUrl parameter should be? – Robert MacLean Feb 28 '10 at 12:01
9

Another option is to use plain ol' HTTP PUT:

WebClient webclient = new WebClient();
webclient.Credentials = new NetworkCredential(_userName, _password, _domain);
webclient.UploadFile(remoteFileURL, "PUT", FilePath);
webclient.Dispose();

Where remoteFileURL points to your SharePoint document library...

Jim Harte
  • 2,593
  • 3
  • 23
  • 20
  • Agree with Erik E though, to then update the meta data you will need to create another version (where versioning for the doc library is turned on). If you do this, the first version will be Version 2 (or 0.2). – misteraidan Jul 01 '09 at 04:04
  • 1
    Not sure this is true, since I don't think the "PUT" will check in the file if versioning is enabled. Also, it should be possible to update metadata without creating a new version by using the SPListItem.SystemUpdate() method... – Jim Harte Jul 01 '09 at 13:20
  • 3
    Does this require changing the default permissions in IIS? I am receiving a 403 Forbidden exception when doing this. – Jeremy Dec 01 '10 at 17:16
  • where can I import all predefined classes? – Shailendra Madda Feb 10 '16 at 12:19
8

There are a couple of things to consider:

  • Copy.CopyIntoItems needs the document to be already present at some server. The document is passed as a parameter of the webservice call, which will limit how large the document can be. (See http://social.msdn.microsoft.com/Forums/en-AU/sharepointdevelopment/thread/e4e00092-b312-4d4c-a0d2-1cfc2beb9a6c)
  • the 'http put' method (ie webdav...) will only put the document in the library, but not set field values
  • to update field values you can call Lists.UpdateListItem after the 'http put'
  • document libraries can have directories, you can make them with 'http mkcol'
  • you may want to check in files with Lists.CheckInFile
  • you can also create a custom webservice that uses the SPxxx .Net API, but that new webservice will have to be installed on the server. It could save trips to the server.
ErikE
  • 857
  • 8
  • 18
  • 1
    For CopyIntoItems, the source url is only informational. The bits don't come from some other server. – Tony Lee Mar 19 '09 at 20:25
  • From my testing today, bullet #1 is incorrect. You can upload an entirely new document to the server with Copy.CopyIntoItems. – retrodrone Jun 24 '11 at 22:08
  • 1
    You are correct. I updated the answer, please note the maximum size issue. – ErikE Jun 28 '11 at 16:50
6
public static void UploadFile(byte[] fileData) {
  var copy = new Copy {
    Url = "http://servername/sitename/_vti_bin/copy.asmx", 
    UseDefaultCredentials = true
  };

  string destinationUrl = "http://servername/sitename/doclibrary/filename";
  string[] destinationUrls = {destinationUrl};

  var info1 = new FieldInformation
                {
                  DisplayName = "Title", 
                  InternalName = "Title", 
                  Type = FieldType.Text, 
                  Value = "New Title"
                };

  FieldInformation[] info = {info1};
  var copyResult = new CopyResult();
  CopyResult[] copyResults = {copyResult};

  copy.CopyIntoItems(
    destinationUrl, destinationUrls, info, fileData, out copyResults);
}

NOTE: Changing the 1st parameter of CopyIntoItems to the file name, Path.GetFileName(destinationUrl), makes the unlink message disappear.

Luke Hutton
  • 10,612
  • 6
  • 33
  • 58
4

I've had good luck using the DocLibHelper wrapper class described here: http://geek.hubkey.com/2007/10/upload-file-to-sharepoint-document.html

Eugene Katz
  • 5,208
  • 7
  • 40
  • 49
1

From a colleage at work:

Lazy way: your Windows WebDAV filesystem interface. It is bad as a programmatic solution because it relies on the WindowsClient service running on your OS, and also only works on websites running on port 80. Map a drive to the document library and get with the file copying.

There is additionally a web service to upload files, painful but works all the time.

I believe you are able to upload files via the FrontPage API but I don’t know of anyone who actually uses it.

Community
  • 1
  • 1
Ben Scheirman
  • 40,531
  • 21
  • 102
  • 137
  • Word, Excel (and other Office apps) use FrontPage API as do many others. In the 2010 version CMIS will be supported. – Lou Franco May 21 '09 at 15:34
1

Not sure on exactly which web service to use, but if you are in a position where you can use the SharePoint .NET API Dlls, then using the SPList and SPLibrary.Items.Add is really easy.

Daniel O
  • 2,810
  • 3
  • 28
  • 35