Skip to content

The Chris Kent

Quick Fixes, Workarounds, and Other Neat Tricks

  • Home
  • About
  • Speaking
Home2015April

Month: April 2015

Using SharePoint RPC to Upload Documents

April 15, 2015April 15, 2015 theChrisKent .NET, List/Library Settings, SharePoint createdir, keep_checked_out, metadata, migrationsemantics, put document, put_option, RPC, SharePoint, VB.NET, WebClient
Applies To: SharePoint, VB.NET

In my last post, Using SharePoint RPC to Create Directories, I showed you the basics of using the SharePoint Foundation RPC Protocol. I provided a lot of the plumbing code needed for executing RPC methods and then demonstrated creating multiple directories in a single call.

In this post, I’ll be building on my SPUploader module to show you how to upload documents while setting the metadata all in a single call. You will need all the code in the first post to make this work.

Uploading Documents

Our goal is to upload a document to a library and set its metadata at the same time using the put document RPC method. There are some additional complications with Office docs that I won’t be addressing, but this should get you started for most file types.

The put document method has four parameters we care about: document, put_option, comment, and keep_checked_out.

Document Details

The document parameter is where you will specify the document name and all meta data. For a document named SomeStuff.csv with a title of “Some Stuff” to be uploaded in the Stuff folder of our Junk library the document parameter needs to look like this:

document=[document_name=Junk/Stuff/SomeStuff.csv;meta_info=[vti_title;SW|Some Stuff]]

Here are some utility functions that will help you generate all the information correctly:

    Private Function documentDetailString(fileName As String, properties As Dictionary(Of String, Object)) As String
        Return String.Format("[document_name={0};meta_info=[{1}]]", EncodeString(fileName), EncodeString(propertiesToString(properties)))
    End Function

    Private Function propertiesToString(properties As Dictionary(Of String, Object)) As String
        If properties Is Nothing Then Return String.Empty
        Dim props As New StringBuilder
        For Each kvp As KeyValuePair(Of String, Object) In properties
            If kvp.Value IsNot Nothing Then
                Dim field As String = kvp.Key
                If field = "Title" Then field = "vti_title"

                Dim value As String
                Dim typeCode As String = "S"
                Select Case (kvp.Value.GetType().FullName)
                    Case "System.Boolean"
                        typeCode = "B"
                        value = IIf(CType(kvp.Value, Boolean), "true", "false")
                    Case "System.DateTime"
                        value = CType(kvp.Value, DateTime).ToString("s") & "Z"
                    Case Else
                        value = escapeVectorCharacters(kvp.Value.ToString)
                End Select

                props.AppendFormat("{0};{1}W|{2};", field, typeCode, value)
            End If
        Next
        Return props.ToString.TrimEnd(";")
    End Function

The first function, documentDetailString (lines 96-98), will help generate the basic structure of the document parameter’s value. It uses the EncodeString function from my last post to escape both the file name and all the metadata information between the brackets. When we use this later in an RPCParameter object you’ll see that we disable additional encoding since RPC is really finicky about this stuff.

The metadata information for a file is generated using the propertiesToString function (lines 100-124) and expects your metadata to be in a dictionary object where the internal column name is the key (string) and the value is the value (object). We loop through each property and build a strange looking string that indicates which column we are setting, the type of the value (and what action we want performed), and the value itself.

Generally, every property key needs to be set to the internal name of the column (not the display name). However, the Title column is a special case. When you specify Title it actually needs to be vti_title. This is taken care of in lines 105-106.

The meta_info string for each property has two parts separated by semicolons. The first is the internal name of the column, the second is information about the value. This second part also has two parts separated by a pipe. The first part will be two characters. The first character indicates the type of the value (S for everything but Boolean values where you will use B). The second character will always be W (write) and specifies the action to take.

We take care of this with a simple case statement that checks the type of the value (line 110). When it’s a Boolean, we use a B for the type character and set the value to the string true or false (lines 111-113). When it’s a DateTime, we still use S for the type character but we format the value into the standard Sortable format and slap a Z on the end (lines 114-115). For everything else, we specify S for type and use our escapeVectorCharacters method to escape it properly (lines 116-117).

Once we’ve looped through all the properties, we remove the final semicolon (line 123).

Unique File Names

Here’s a freebie function should you need it:

    Public Function UniqueFileName(originalFileName As String) As String
        Return "C" & DateTime.Now.ToString("yyMMddHHmmssfffffff") & "K" & Path.GetExtension(originalFileName)
    End Function

The UniqueFileName function above is a quick and dirty way to ensure that you aren’t overwriting your documents when uploading them in bulk.

Uploading

    Public Function UploadToSharePoint(webURL As String, libraryName As String, FolderPath As String, FileName As String, fileBytes As Byte(), properties As Dictionary(Of String, Object), SPVersion As String, Optional creds As NetworkCredential = Nothing, Optional KeepCheckedOut As Boolean = False, Optional Comment As String = "") As String
        Dim result As String = String.Empty

        If Not (String.IsNullOrEmpty(webURL) OrElse String.IsNullOrEmpty(libraryName) OrElse String.IsNullOrEmpty(FileName)) Then

            If properties Is Nothing Then properties = New Dictionary(Of String, Object)
            If Not (properties.ContainsKey("Title") OrElse properties.ContainsKey("vti_title")) Then
                properties.Add("Title", Path.GetFileNameWithoutExtension(FileName))
            End If

            Dim parameters As New List(Of RPCParameter)
            parameters.Add(New RPCParameter("document", documentDetailString(libraryName & "/" & FolderPath & "/" & FileName, properties), False, False))
            parameters.Add(New RPCParameter("put_option", "overwrite,createdir,migrationsemantics", False, False)) 'Overwrites files (otherwise use edit),creates the directory as needed, preserves creation/modification information
            parameters.Add(New RPCParameter("comment", Comment))
            parameters.Add(New RPCParameter("keep_checked_out", IIf(KeepCheckedOut, "true", "false")))

            Dim data As New List(Of Byte)
            'put document method: http://msdn.microsoft.com/en-us/library/ms479623(v=office.14).aspx
            data.AddRange(CommandBytes("put document", SPVersion, parameters))
            data.AddRange(Encoding.UTF8.GetBytes(vbLf))
            data.AddRange(fileBytes)

            result = ExecuteRPC(webURL, data.ToArray, creds)

        End If

        Return result
    End Function

End Module

The UploadToSharePoint function takes a web URL (this does not have to be the root site in a site collection), the name of the library to upload into, the folderpath (only the immediate directory will be created if needed, if you need to create a full path of directories or ensure they are there, use the CreateFolder function demonstrated in the previous post), the filename (great time to use that UniqueFileName function!), the filebytes, a property dictionary (string, object), the SharePoint version, and some optional parameters (credentials, keepcheckedout, version comments).

If the property dictionary doesn’t contain a Title property, we automatically add one using the filename without the extension (lines 136-138). Now it’s time to create the method parameters.

The first parameter for the put document method is the document parameter (line 141) which we create using the documentDetailString function. Notice that we don’t just specify the filename, but rather the exact path (library + folderpath + filename). We also disable string encoding in the RPCParameter object since this parameter requires very specific encoding that is handled in our helper function.

The second parameter, put_option, is where we specify some combination of the following three strings separated by commas:

  • overwrite: overwrites existing files with the same filename
  • createdir: creates the parent directory (does not create a full path)
  • migrationsemantics: preserves the author, editor and creation information (requires administrative permissions or it is ignored)

For our purposes we are specifying all three (line 142).

The third parameter, comment, is a comment to include for the given version of the file (line 143).

The final parameter, keep_checked_out, takes a string of “true” or “false” (line 144). When true, the document is checked in then checked right back out. When false, the document is just checked in.

To upload the document we must specify all of the method parameters first. We generate the appropriate bytes using our CommandBytes function (line 148). We then have to add the actual file bytes (line 150) but these need to be separated from the command bytes with a line feed (line 149).

 

That’s it! Now you can upload documents while setting the metadata all in a single call!

Rate this:

Share this:

  • Twitter
  • Facebook
  • More
  • Print
  • Email
  • Tumblr
  • Pinterest
  • Reddit
  • LinkedIn

Like this:

Like Loading...
Leave a comment

Office Development

Recent Posts

  • Thank you Microsoft 365 Conference!
  • Getting the Binary Value of an ASCII Character in Power Apps
  • Converting Integers to Binary in Power Apps
  • Converting Binary to Integers in Power Apps
  • Thank you M365 Collaboration Conference!

Popular Posts

  • Applying Column Formats to Multi-line Text Fields
  • Custom Icon Buttons in Power Apps with Hover Color
  • Generate List Formatting Elements in a Loop Using forEach
  • Formatting Values Using "Contains" in List Formatting
  • Validate Email Address Columns in SharePoint

Archives

  • December 2022
  • May 2022
  • April 2022
  • May 2021
  • June 2020
  • April 2020
  • November 2019
  • May 2019
  • April 2019
  • March 2019
  • February 2019
  • January 2019
  • December 2018
  • August 2018
  • July 2018
  • May 2018
  • April 2018
  • March 2018
  • February 2018
  • January 2018
  • December 2017
  • November 2017
  • October 2017
  • September 2017
  • August 2017
  • July 2017
  • June 2017
  • May 2017
  • April 2017
  • March 2017
  • February 2017
  • January 2017
  • December 2016
  • November 2016
  • October 2016
  • September 2016
  • August 2016
  • July 2016
  • June 2016
  • May 2016
  • April 2016
  • March 2016
  • February 2016
  • January 2016
  • August 2015
  • April 2015
  • February 2015
  • September 2014
  • August 2014
  • July 2014
  • June 2014
  • May 2014
  • April 2014
  • March 2014
  • February 2014
  • January 2014
  • December 2013
  • November 2013
  • October 2013
  • August 2013
  • March 2013
  • February 2013
  • January 2013
  • November 2012
  • October 2012
  • September 2012
  • August 2012
  • July 2012
  • June 2012
  • May 2012
  • April 2012
  • March 2012
  • February 2012
Create a website or blog at WordPress.com
  • LinkedIn
  • Twitter
  • Follow Following
    • The Chris Kent
    • Join 367 other followers
    • Already have a WordPress.com account? Log in now.
    • The Chris Kent
    • Customize
    • Follow Following
    • Sign up
    • Log in
    • Report this content
    • View site in Reader
    • Manage subscriptions
    • Collapse this bar
%d bloggers like this: