Pages

Wednesday, April 20, 2016

Download Attachments From List Items In SharePoint 2013 Online Console Application

Introduction

In this post, I will show how to connect to SharePoint 2013 Online, get the list item attachment(s) from the SharePoint 2013 Online custom list and download it to the local folder of our drive.

Prerequisites

The prerequisites required are:
  • Knowledge of SharePoint Client Object Model
  • Knowledge of C# and Console Application
  • Reference of files i.e. "Microsoft.SharePoint.Client.dll" and "Microsoft.SharePoint.Client.Runtime.dll" in Console Application

 

Let's Start...

 

Step 1. Create a new custom list in SharePoint 2013 Online as "TestAttachmentList"

Step 2. Add an item to a list and attach few files with it

Step 3. Just to check, view the item you have added and see if it has files attached.
For example, I have created an item with "Title" as "Test 1" and have added 3 text files as shown below:


Step 4. Now, create a console application in Visual Studio and add two reference files to your solution i.e. "Microsoft.SharePoint.Client.dll" and "Microsoft.SharePoint.Client.Runtime.dll"


Step 5. In your Console Application's main function, write below code with appropriate changes i.e. SharePoint 2013 Online site URL, SharePoint 2013 Online credentials, file path to create folder and save attachments:

using (ClientContext clientContext = new ClientContext("https://mysite.sharepoint.com/sites/Site")) 
            {
                SecureString passWord = new SecureString();
                foreach (char c in "mypassword".ToCharArray()) passWord.AppendChar(c);
                clientContext.Credentials = new SharePointOnlineCredentials("sunny.bahree@mysite.com", passWord);
                Web web = clientContext.Web;
                clientContext.Load(web);
                clientContext.ExecuteQuery();
                CamlQuery query = new CamlQuery();
                query.ViewXml = @"";
                List oList = clientContext.Web.Lists.GetByTitle("TestAttachmentList");
                clientContext.Load(oList);
                clientContext.ExecuteQuery();
                ListItemCollection items = oList.GetItems(query);
                clientContext.Load(items);
                clientContext.ExecuteQuery();
                foreach (ListItem listItem in items)
                {
                    Folder folder = web.GetFolderByServerRelativeUrl(clientContext.Url + "/Lists/TestAttachmentList/Attachments/" + listItem["ID"]);
                    clientContext.Load(folder);
                    try
                    {
                        clientContext.ExecuteQuery();
                    }
                    catch (ServerException ex)
                    {
                        Console.WriteLine(ex.Message);
                        Console.WriteLine("No Attachment for ID " + listItem["ID"].ToString());
                    }

                    FileCollection attachments = folder.Files;
                    clientContext.Load(attachments);
                    clientContext.ExecuteQuery();
                    DirectoryInfo dir = Directory.CreateDirectory(@"C:/Downloads/" + listItem["ID"].ToString());
                    foreach (Microsoft.SharePoint.Client.File oFile in folder.Files)
                    {
                        Console.WriteLine("Found Attachment for ID " + listItem["ID"].ToString());
                        FileInfo myFileinfo = new FileInfo(oFile.Name);
                        using (WebClient client1 = new WebClient())
                        {
                            client1.Headers["Accept"] = "/";
                            client1.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
                            client1.Credentials = clientContext.Credentials;
                            client1.DownloadFile("https://mysite.sharepoint.com" + oFile.ServerRelativeUrl, @"C:/Downloads/" + listItem["ID"].ToString() + "/" + oFile.Name);
                            Console.WriteLine("Downloading " + oFile.ServerRelativeUrl);
                        }
                    }
                }

                Console.WriteLine("All files have downloaded!");
                Console.ReadLine();
            }


In above code, we can see that by passing our SharePoint 2013 Online credentials, we can connect to the SharePoint 2013 Online site and from there we can access the custom list along with custom list's all items with their attachments.

To separate the attachments attached per item, we are creating separate folder per item in a our drive with the item ID as a folder name and in that folder we are storing the respective attachments for an item.

Once we run the console application, it will create folder and add files to the folder similar to this:

.
As we can see in above screenshot, after creating a folder (i.e. "1"), we get all the files we have attached to the list item in it.

If I will open each of the files, it will show me the content I have added into them as shown below:


Complete Code

 

Here is the complete code of the Console Application:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security;
using System.Text;
using Microsoft.SharePoint.Client;
using System.IO;
using System.Net;
namespace ConsoleAPPDownloadSPAttachments
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ClientContext clientContext = new ClientContext("https://mysite.sharepoint.com/sites/Site"))
            {
                SecureString passWord = new SecureString();
                foreach (char c in "mypassword".ToCharArray()) passWord.AppendChar(c);
                clientContext.Credentials = new SharePointOnlineCredentials("sunny.bahree@mysite.com", passWord);
                Web web = clientContext.Web;
                clientContext.Load(web);
                clientContext.ExecuteQuery();
                CamlQuery query = new CamlQuery();
                query.ViewXml = @"";
                List oList = clientContext.Web.Lists.GetByTitle("TestAttachmentList");
                clientContext.Load(oList);
                clientContext.ExecuteQuery();
                ListItemCollection items = oList.GetItems(query);
                clientContext.Load(items);
                clientContext.ExecuteQuery();
                foreach (ListItem listItem in items)
                {
                    Folder folder = web.GetFolderByServerRelativeUrl(clientContext.Url + "/Lists/TestAttachmentList/Attachments/" + listItem["ID"]);
                    clientContext.Load(folder);
                    try
                    {
                        clientContext.ExecuteQuery();
                    }
                    catch (ServerException ex)
                    {
                        Console.WriteLine(ex.Message);
                        Console.WriteLine("No Attachment for ID " + listItem["ID"].ToString());
                    }

                    FileCollection attachments = folder.Files;
                    clientContext.Load(attachments);
                    clientContext.ExecuteQuery(); 
                    DirectoryInfo dir = Directory.CreateDirectory(@"C:/Downloads/" + listItem["ID"].ToString());
                    foreach (Microsoft.SharePoint.Client.File oFile in folder.Files)
                    {
                        Console.WriteLine("Found Attachment for ID " + listItem["ID"].ToString());
                        FileInfo myFileinfo = new FileInfo(oFile.Name);
                        using (WebClient client1 = new WebClient())
                        {
                            client1.Headers["Accept"] = "/";
                            client1.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
                            client1.Credentials = clientContext.Credentials;                          
client1.DownloadFile(
"https://mysite.sharepoint.com" + oFile.ServerRelativeUrl, @"C:/Downloads/" + listItem["ID"].ToString() + "/" + oFile.Name);
                            Console.WriteLine("Downloading " + oFile.ServerRelativeUrl);
                        }
                    }
                }
                Console.WriteLine("All files have downloaded!");
                Console.ReadLine();
            }
        }
    }
}

Conclusion

In this post, we learnt how to connect to SharePoint 2013 Online site using Console Application and then get the items from SharePoint 2013 Online custom list along with attachments and download the attachments to our local drive folder.

Read More »

Friday, April 15, 2016

How to Add Item or Data In Survey List's Rating Scale Column in SharePoint

Introduction

Survey lists are useful lists when it comes to getting a feedback from bulk of people. It provides lots of column types by which we can create questions. It also provides a column type name as "Rating Scale".

To know more about Rating Scale column, click here!

Here, I will demonstrate how to add an item to a Survey list particularly in to this "Rating Scale" column type and it's sub questions.

Prerequisites


Here, prerequisites requires knowledge of:

2. CSOM
3. JQuery


Let's get started...

Let's create a test survey list in SharePoint and we will name it as "TestSurvey".

In this list, we will add 3 questions or columns:

1. Requester Name - Single Line of Text as a column type



2. Supplier Name - Single Line of Text as a column type


3.  How would you rate Vendor in the below categories? - Rating Scale as a column type

So, in above Rating Scale question, as we can see that the main question heading/title is "How would you rate Vendor in the below categories?" and the sub- questions are:
"Overall performance", "Quality of deliverable", "Timeliness", "Ease of use (how easy it was to work with the vendor and/or their system)", "Cost" (all in separate lines).

"Number Range", I have kept as is and it is set to 5. "Range Text" is showing "Low", "Average" and "High".


This is how our Survey's new form will looks like:


Our Survey list is ready with questions along with our Rating Scale set of questions.

We will now add a response to this Survey using custom code.

Adding data to Survey using code

Adding a response to "Single line of text" type column is straight forward but when it comes to "Rating Scale" type column, we have to consider few things.

For adding/inserting data to "Rating Scale" type column, we need to first enter the sub-category question text and then separate its rating by ";#" then enter rating and then again put "#". 

For e.g., in our case "Overall performance" is a sub-category question. So, when adding/inserting the data for this sub-category question to the Survey list, we will separate it like - "Overall performance;#5#". 

This will insert rating of "Overall performance" as "5". If you notice, I have given the exact text of a sub-category question including the spaces.

To add ratings to other columns, for e.g., this time we will add rating to "Overall performance" and "Quality of deliverable", we will format our code as following:
"Overall performance;#5#Quality of deliverable;#4#".

This will insert "Overall performance" rating with "5" and "Quality of deliverable" as "4".

The exact code will be:

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
    <script type="text/javascript" src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#btnSave").click(function () {
                SaveData();
            });
        });

        function SaveData() {
            var currClientContext = new SP.ClientContext.get_current();
            var currList = currClientContext.get_web().get_lists().getByTitle('TestSurvey');
            var itemCreateInfo = new SP.ListItemCreationInformation();
            var oListItem = currList.addItem(itemCreateInfo);
            oListItem.set_item('Requester_x0020_Name', "Sunny Bahree");
            oListItem.set_item('Supplier_x0020_Name', "Sunny Bahree");
            oListItem.set_item('How_x0020_would_x0020_you_x0020_', "Overall performance;#5#Quality of deliverable;#4#Timeliness;#3#Ease of use (how easy it
was to work with the vendor and/or their system);#4#Cost;#5#"
);
            oListItem.update();
            currClientContext.load(oListItem);
            currClientContext.executeQueryAsync(onQuerySucceeded, onQueryFailed);
            function onQuerySucceeded() {
            }

            function onQueryFailed(sender, args) {
                console.log('Request failed for TestSurvey function. ' + args.get_message() + '\n' + args.get_stackTrace());
            }
        }
    </script>
</head>
<body>
    <input type="button" id="btnSave" value="Save" />
</body>
</html>

As you can see in above code, I have added a "Save" button to a page and clicking on this "Save" button will add and save response to the "Survey" list with "Requester Name" and "Supplier Name" as "Sunny Bahree".

To the question of "How would you rate the Vendor in the below categories?", the sub-category questions i.e. "Overall performance" will have rating as "5", "Quality of deliverable" will have rating as "4", "Timeliness" will have "3", "Ease of use" will have "4" and "Cost" will have rating as "5".

This how the response will look like after it gets saved into our "TestSurvey" list:


Conclusion

We have seen in this post on how we can add ratings to a Survey list using custom code particularly to a Rating Scale column. Hope it will help!

Read More »