3

I'm developing VSTO Outlook Add-In, so I'm using SharePoint Client Object Model. Can I upload a document to SharePoint doc. library and add metadata with one action? Using Google I have found many samples where metadata is added after uploading. Also I found out that it is possible to add metadata using full API(File.Add() method and a hashtable).

Help?

2 Answers 2

4

You could use code like this:

ClientContext context = new ClientContext("SITEURL");
Site site = context.Site;
Web web = context.Web;
context.Load(site);
context.Load(web);
context.ExecuteQuery();

List list = listCollection.GetByTitle("Reports");
context.Load(list);
context.ExecuteQuery();

context.Load(list.RootFolder);
context.Load(list.RootFolder.Folders);
context.ExecuteQuery();

foreach (Folder folder in list.RootFolder.Folders)
{
    if (folder.Name == "Folder-To-Upload")
    {
        FileCreationInformation fci = new FileCreationInformation();

        byte[] array = System.IO.File.ReadAllBytes("SlmReportPeriods.xml"); // File which you want to upload

        fci.Content = array;
        fci.Overwrite = true;
        fci.Url = "Sample";
        File file = folder.Files.Add(fci);


        ListItem item = file.ListItemAllFields;
        item["Field1"] = "Example1";
        item["Field2"] = "ETC.";
        item.Update();

        folder.Files.Add(fci);
        context.ExecuteQuery();
    }
}

The essence of this sample is to use FileCreationInformation and File objects and get ListItemAllFields of item.

Sign up to request clarification or add additional context in comments.

Comments

0

Redzio's answer worked for me.

Following code was derived from blog post Upload Large Files to SharePoint Online (by Piyush K Singh):

public File UploadLargeFileWithMetadata(ClientContext ctx, List docs, string fileName) {
    int blockSize = 8000000; // 8 MB
    string uniqueFileName = String.Empty;
    long fileSize;
    Microsoft.SharePoint.Client.File uploadFile = null;
    Guid uploadId = Guid.NewGuid();

    ctx.Load(docs.RootFolder, p = >p.ServerRelativeUrl);

    // Use large file upload approach
    ClientResult < long > bytesUploaded = null;

    FileStream fs = null;
    try {
        fs = System.IO.File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

        fileSize = fs.Length;
        uniqueFileName = System.IO.Path.GetFileName(fs.Name);

        using(BinaryReader br = new BinaryReader(fs)) {
            byte[] buffer = new byte[blockSize];
            byte[] lastBuffer = null;
            long fileoffset = 0;
            long totalBytesRead = 0;
            int bytesRead;
            bool first = true;
            bool last = false;

            // Read data from filesystem in blocks
            while ((bytesRead = br.Read(buffer, 0, buffer.Length)) > 0) {
                totalBytesRead = totalBytesRead + bytesRead;

                // We've reached the end of the file
                if (totalBytesRead <= fileSize) {
                    last = true;
                    // Copy to a new buffer that has the correct size
                    lastBuffer = new byte[bytesRead];
                    Array.Copy(buffer, 0, lastBuffer, 0, bytesRead);
                }

                if (first) {
                    using(MemoryStream contentStream = new MemoryStream()) {
                        // Add an empty file.
                        FileCreationInformation fileInfo = new FileCreationInformation();
                        fileInfo.ContentStream = contentStream;
                        fileInfo.Url = uniqueFileName;
                        fileInfo.Overwrite = true;
                        uploadFile = docs.RootFolder.Files.Add(fileInfo);

                        // Start upload by uploading the first slice.
                        using(MemoryStream s = new MemoryStream(buffer)) {
                            // Call the start upload method on the first slice
                            bytesUploaded = uploadFile.StartUpload(uploadId, s);
                            ctx.ExecuteQuery();
                            // fileoffset is the pointer where the next slice will be added
                            fileoffset = bytesUploaded.Value;
                        }
                        ListItem Subs = uploadFile.ListItemAllFields;
                        Subs["Title"] = Convert.ToString(CompanyName.Value);
                        Subs["Address"] = Convert.ToString(Address.Value);
                        Subs["City"] = Convert.ToString(City.Value);
                        Subs["State"] = Convert.ToString(State.Value);
                        Subs["Zip"] = Convert.ToString(Zip.Value);
                        Subs["Country"] = Convert.ToString(Country.Value);
                        Subs["Website"] = Convert.ToString(WebSite.Value);
                        Subs.Update();
                        // we can only start the upload once
                        first = false;
                    }
                }
                else {
                    // Get a reference to our file
                    uploadFile = ctx.Web.GetFileByServerRelativeUrl(docs.RootFolder.ServerRelativeUrl + System.IO.Path.AltDirectorySeparatorChar + uniqueFileName);

                    if (last) {
                        // Is this the last slice of data?
                        using(MemoryStream s = new MemoryStream(lastBuffer)) {
                            // End sliced upload by calling FinishUpload
                            uploadFile = uploadFile.FinishUpload(uploadId, fileoffset, s);
                            ctx.ExecuteQuery();

                            // return the file object for the uploaded file
                            return uploadFile;
                        }
                    }
                    else {
                        using(MemoryStream s = new MemoryStream(buffer)) {
                            // Continue sliced upload
                            bytesUploaded = uploadFile.ContinueUpload(uploadId, fileoffset, s);
                            ctx.ExecuteQuery();
                            // update fileoffset for the next slice
                            fileoffset = bytesUploaded.Value;
                        }
                    }
                }

            }

        }
    }
    catch(Exception ex) {
        this.Ex.Text = ex.ToString();
    }
    finally {
        if (fs != null) {
            fs.Dispose();

        }
    }
    return uploadFile;
}

1 Comment

Good research, including the link. Please pay attention to proper code-formatting (e.g. using C# online formatter. If you can add own explanations it would make your answer even better :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.