How to get list of SharePoint Lists in SharePoint 2013 Online using CSOM

In this post, we’ll see how to get the list of the SharePoint List in SharePoint 2013 Online using CSOM.

Open Visual Studio 2013.

File –> New –> Project –> Visual C# –> Console Application  and name it as ‘ReadSharePointLists’

Add a reference to assemblies ‘Microsoft.SharePoint.Client’ and ‘Microsoft.SharePoint.Client.Runtime’.

Import the following two namespaces.

using Microsoft.SharePoint.Client;
using System.Security;

Copy and paste the following snippet of the code that will help us to fetch the list of SharePoint lists in the SharePoint Online site.

namespace ReadSharePointLists
{
    class Program
    {
        static void Main(string[] args)
        {
            //Replace it with the url of your tenant or your site-collection
            string SiteUrl = "https://yoursite.sharepoint.com";

            System.Uri oUri = new System.Uri(SiteUrl);

            using (ClientContext oClientContext = new ClientContext(SiteUrl))
            {
                //Replace it with your user id for SharePoint Online
                string UserName = "userid@yoursite.onmicrosoft.com";


                //Replace it with your password
                string Password = "password";

                //Create a SecureString object from password string, needed for SharePointOnlineCredentials class
                SecureString SecurePassword = GetSecureString(Password);
                oClientContext.Credentials = new SharePointOnlineCredentials(UserName, SecurePassword);

                //load the properties of web object
                Web oWeb = oClientContext.Web;
                
                //Get all the lists in the web
                oClientContext.Load(oWeb.Lists);
                oClientContext.ExecuteQuery();


                foreach (List oList in oWeb.Lists)
                {
                    Console.WriteLine(oList.Title.ToString());
                
                }
                Console.ReadLine();


            
            }

        }

        private static SecureString GetSecureString(String Password)
        {
            SecureString oSecurePassword = new SecureString();

            foreach (Char c in Password.ToCharArray())
            {
                oSecurePassword.AppendChar(c);

            }
            return oSecurePassword;
        }

    }
}

 

After executing this we’ll see the below result, which displays the names of the SharePoint lists in the SharePoint 2013 Online site.clip_image002

 Subscribe to my blog

Largest collection of free Microsoft eBooks

Largest collection of FREE Microsoft eBooks ever, including: Windows 8.1, Windows 8, Windows 7, Office 2013, Office 365, Office 2010, SharePoint 2013, Dynamics CRM, PowerShell, Exchange Server, Lync 2013, System Center, Azure, Cloud, SQL Server can be downloaded here in the msdn blog.

http://blogs.msdn.com/b/mssmallbiz/archive/2014/07/07/largest-collection-of-free-microsoft-ebooks-ever-including-windows-8-1-windows-8-windows-7-office-2013-office-365-office-2010-sharepoint-2013-dynamics-crm-powershell-exchange-server-lync-2013-system-center-azure-cloud-sql.aspx

I’d like to thank Eric Ligman for collating this and publishing this in MSDN blog.

 

Configure internet access in Microsoft Azure Virtual Network

I’m setting up a Virtual Network in Azure to host my SharePoint 2013 farm. I’ve configured added the DNS servers of 10.0.0.4 and 10.0.0.5 (as per my pervious article), expecting that I would be able to access the public internet inside the SharePoint 2013 VM’s. I’m able to access only google and few other internet sites inside the VMs, most of the sites including microsoft.com was not accessible.

The fix for this issue is to add the Public DNS servers (168.63.129.16 and 168.62.167.9) to the list of DNS servers in the Azure Virtual Network.

image

After adding the Public DNS servers (168.63.129.16 and 168.62.167.9) , the internet connectivity worked like a charm.

 Subscribe to my blog

Consume a SharePoint 2013 Online REST feed using .NET managed code

In this post, we’ll see how we can consume a SharePoint 2013 online REST feed using managed c# code. I’d be using a Provider Hosted App template in Visual Studio 2013 for this demonstration. It is very straight forward to consume a Restful .NET service by issuing HttpWebRequest from c# code and getting HttpWebResponse.

I will be invoking https://yoursite.sharepoint.com/_api/web/lists from c# code to get the list of SharePoint lists in this Office 365 site. The following screenshot shows the response for this Restful service in the browser.

image

Now let’s start creating a Provider hosted app project in Visual Studio 2013.

File –> New Project –> Visual C# –> Office/SharePoint –> App for SharePoint 2013 and name it as ‘ReadRESTCSharp’ & set the site for debugging and app type as ‘Provider-hosted’.

image

Specify the web project type as ‘ASP.NET Web Forms Application’. In the next step, Visual Studio 2013 would prompt for setting App Authentication Type, I did not see this option while using Visual Studio 2012 to create Provider hosted apps.

image

Set the App authentication type as ‘Use Windows Azure Access Control Service’ (mentioned in the above screenshot).

Click ‘Finish’ to create the app.

Go to  ASP.NET Web Forms project and open the default.aspx.cs

Import the following three namespaces at the top.

using Microsoft.SharePoint.Client;
using System.Net;
using System.IO;

In page_load comment out the following lines of code.

//var spContext = SharePointContextProvider.Current.GetSharePointContext(Context);

            //using (var clientContext = spContext.CreateUserClientContextForSPHost())
            //{
              //  clientContext.Load(clientContext.Web, web => web.Title);
               // clientContext.ExecuteQuery();
                //Response.Write(clientContext.Web.Title);
            //}

Since I’m using my own developer tenant in Office 365, I would want to trust all the certificates issued by SharePoint Online to my browser. Otherwise, it will keeping popping up a message to trust the certificates in Visual Studio 2013, when I hit F5 and debug the app.

Open the TokenHelper.cs and the add the following static method ‘TrustAllCertificates’

public static void TrustAllCertificates()
        {
            //Trust all certificates
            System.Net.ServicePointManager.ServerCertificateValidationCallback =
                ((sender, certificate, chain, sslPolicyErrors) => true);
        }

If you are using Visual Studio 2012, it adds ‘TrustAllCertificates’ in TokenHelper.cs by default.

I will be using my Office 365 developer tenant for this demo, which forces the need to get the Access Token from Office 365 and pass it as a part of the header in the HttpWebRequest. First I need to get the ContextTokenString by invoking GetContextTokenFromRequest method in TokenHelper.cs. Then I need to get the actual SharePointContextToken by invoking ReadAndValidateContextToken method in the TokenHelper.cs. Finally I need to get AccessToken by invoking the GetAccessToken method in the TokenHelper.cs. I won’t go too detailed about this one. All the dynamics of the Token exchange is covered in one of my previous article.

Once the AccessToken is received, a HTTPWebRequest needs to be issued by setting the AccessToken with Bearer, also we need to set the HTTPRequest method as ‘GET’ and HTTPRequest accept headers as “application/json;odata=verbose”.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.IO;
using Microsoft.SharePoint.Client;

namespace ReadRESTCSharpWeb
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_PreInit(object sender, EventArgs e)
        {
            Uri redirectUrl;
            switch (SharePointContextProvider.CheckRedirectionStatus(Context, out redirectUrl))
            {
                case RedirectionStatus.Ok:
                    return;
                case RedirectionStatus.ShouldRedirect:
                    Response.Redirect(redirectUrl.AbsoluteUri, endResponse: true);
                    break;
                case RedirectionStatus.CanNotRedirect:
                    Response.Write("An error occurred while processing your request.");
                    Response.End();
                    break;
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            
            // The following code gets the client context and Title property by using TokenHelper.
            // To access other properties, the app may need to request permissions on the host web.
            //var spContext = SharePointContextProvider.Current.GetSharePointContext(Context);

            //using (var clientContext = spContext.CreateUserClientContextForSPHost())
            //{
              //  clientContext.Load(clientContext.Web, web => web.Title);
               // clientContext.ExecuteQuery();
                //Response.Write(clientContext.Web.Title);


            //}

            TokenHelper.TrustAllCertificates();

            //Get the ContextTokenString
            string ContextTokenString = TokenHelper.GetContextTokenFromRequest(Request);



            if (ContextTokenString != null)
            {

                //Get the SharePointContextToken
                SharePointContextToken ContextToken = TokenHelper.ReadAndValidateContextToken(ContextTokenString, Request.Url.Authority);

                Uri sharepointUrl = new Uri(Request.QueryString["SPHostUrl"]);

                //Get the AccessToken
                string AccessToken = TokenHelper.GetAccessToken(ContextToken,sharepointUrl.Authority).AccessToken;

                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(@"https://yoursite.sharepoint.com/_api/web/lists");
                request.Method = "GET";
                request.Accept = "application/json;odata=verbose";
                request.Headers.Add("Authorization", "Bearer " + AccessToken);

                HttpWebResponse response =(HttpWebResponse)request.GetResponse();
                StreamReader reader = new StreamReader(response.GetResponseStream());

                Response.Write("<h2>List of SharePoint lists in SharePoint Online fetched from managed code</h2>");
                Response.Write("<p>" + reader.ReadToEnd() + "</p>");
                Response.Flush();
            
            
            }




        }
    }
}

After executing the above we get the successful HTTPResponse which can be seen in debug mode in Visual Studio 2013.

image

  Subscribe to my blog

How to retrieve current user in SharePoint 2013 Online using CSOM

In this post, we’ll see how we can retrieve the current user in a SharePoint 2013 online site using client side object model (CSOM). We’ll  be using a console application for the purpose of this demonstration.

Open Visual Studio 2013

File –> New Project –> C# –> Console application

Add  reference to the following assemblies.

Microsoft.SharePoint.Client.dll

Microsoft.SharePoint.Client.runtime.dll

Import the following namespaces at the top of Program.cs

using  Microsoft.SharePoint.Client;
using System.Security;

namespace Retrievecurrentuser
{
    class Program
    {
        static void Main(string[] args)
        {

            using (ClientContext oClientContext = new ClientContext(@"https://yoursite.sharepoint.com"))
            {

                //Assign User Id for your SharePoint Online tenant     
                string UserName = "userid@yoursite.onmicrosoft.com";

                //Assign password for your SharePoint online tenant
                string Password = "password";

                //Create a SecureString object from password string, needed for SharePointOnlineCredentials class
                SecureString SecurePassword = GetSecureString(Password);
                oClientContext.Credentials = new SharePointOnlineCredentials(UserName, SecurePassword);


                //load the properties of web object
                Web oWeb = oClientContext.Web;
                oClientContext.Load(oWeb);
                oClientContext.ExecuteQuery();

                //retrieve the site name
                string SiteName = oWeb.Title;

                //retrieve the current user
                oClientContext.Load(oWeb.CurrentUser);
                oClientContext.ExecuteQuery();

            Console.WriteLine("Login Name"+ oClientContext.Web.CurrentUser.LoginName);
                Console.WriteLine("Is Admin"+ oClientContext.Web.CurrentUser.IsSiteAdmin);
                Console.WriteLine("Email"+ oClientContext.Web.CurrentUser.Email);
                
                Console.ReadLine();


            }
        }

        private static SecureString GetSecureString(String Password)
        {
            SecureString oSecurePassword = new SecureString();

            foreach (Char c in Password.ToCharArray())
            {
                oSecurePassword.AppendChar(c);

            }
            return oSecurePassword;
        }

    }
}

Then create a clientcontext in the program.cs, load the web object (execute query) and then load the current user based on the web object.

Now we’ll be able to fetch the user properties like the below.

image

 Subscribe to my blog

How to create a site-collection using CSOM in SharePoint Online

In this post, we’ll see how to create a site-collection using SharePoint 2013 CSOM in SharePoint Online. We’ll be using a console application for the purpose of demonstration.

Open Visual Studio 2013 –> File –> New –> Console Application and name it as ‘CreateSiteCollCSOM’.

Add references to the following assemblies

Microsoft.SharePoint.Client.dll

Microsoft.SharePoint.Client.runtime.dll

Microsoft.Online.SharePoint.Client.Tenant.dll

.

The Microsoft.Online.SharePoint.Client.Tenant.dll will be available in the location C:Program FilesSharePoint Client ComponentsAssemblies, if the SharePoint Client Components SDK is installed.

Import the following namespaces at the top of Program.cs

using  Microsoft.SharePoint.Client;
using System.Security;
using Microsoft.Online.SharePoint.TenantAdministration;

static void Main(string[] args)
        {
            


            using (ClientContext oClientContext = new ClientContext("https://yoursite-admin.sharepoint.com"))
            {
                //Assign User Id for your SharePoint Online tenant     
                string UserName = "userid@yoursite.onmicrosoft.com";

                //Assign password for your SharePoint online tenant
                string Password = "password";

                //Create a SecureString object from password string, needed for SharePointOnlineCredentials class
                SecureString SecurePassword = GetSecureString(Password);

                oClientContext.Credentials = new SharePointOnlineCredentials(UserName, SecurePassword);
                

                var oTenant = new Tenant(oClientContext);

                var oSiteCreationProperties = new SiteCreationProperties();


                //Set the url of site-collection to be created
                oSiteCreationProperties.Url = "https://yoursite.sharepoint.com/sites/TestSiteColl";

                //Set the title of site
                oSiteCreationProperties.Title = "Test SiteColl from code";

                //set the site-collection owner
                oSiteCreationProperties.Owner = "userid@yoursite.onmicrosoft.com";

                //set the template of site-collection to be created as TeamSite
                oSiteCreationProperties.Template = "STS#0";

                //set the storge maxium level in MB
                oSiteCreationProperties.StorageMaximumLevel = 200;

                oSiteCreationProperties.UserCodeMaximumLevel = 100;



                SpoOperation oSpoOperation = oTenant.CreateSite(oSiteCreationProperties);

                oClientContext.Load(oTenant);

                oClientContext.Load(oSpoOperation, i=>i.IsComplete);
                oClientContext.ExecuteQuery();

               

                Console.WriteLine("SiteCollection successfully reated");




            }




        }

        private static SecureString GetSecureString(String Password)
        {
            SecureString oSecurePassword = new SecureString();

            foreach (Char c in Password.ToCharArray())
            {
                oSecurePassword.AppendChar(c);

            }
            return oSecurePassword;
        }

Azure WebJobs – Q&A’s

Here are some important Q&A’s around AzureWebjobs.

1. What is WebJobs in Azure?

The WebJobs in Azure enables us to run programs or scripts in Azure web sites in one of the following 3 ways :-

  • On Demand
  • Continuously
  • Scheduled

 

2. What are the acceptable file types for Scripts to create WebJobs?

It supports the set of file types creating using the following technologies:-

  • using windows cmd (.cmd, .bat and .exe)
  • using powershell (.ps1)
  • using bash (.sh)
  • using php (.php)
  • using python (.py)
  • using node (.js)

3. Where are WebJobs deployed?

WebJobs are deployed as a part of web site or ftp-ed into a specific directory. Once the WebJobs is deployed to the Azure web site, it gives an extra dashboard which details out the job execution history.

4. How to set up a WebJobs?

First you need to create an Azure web site for setting up the WebJobs. Click WebJobs (preview) at the top and click Add at the bottom. Then zip the contents of job folders and project and upload it.

5. What is the significance of Azure scheduler in the context of WebJobs?

To schedule a WebJobs, we need to have Azure scheduler enabled.

6. What is the cost for running WebJobs?

As of now, three is no additional cost for using Azure WebJobs unless AlwaysOn feature is turned on.

7. What is the maximum allowed file size for content (.zip files) submitted to WebJobs?

The maximum allowed file size for the content (.zip files) submitted to WebJobs is 100 MB. The .zip file should contain the executables (in any one of the formats like .exe, .cmd, .bat, .sh, .php, .py and .js).

 

 

 

 

How to create a SharePoint 2013 Site by invoking SP 2013 REST endpoints

In this post, we would see on how to create a SharePoint 2013 site using the SharePoint 2013 RESTful endpoints available in HostWeb. I would be using a SharePoint hosted app to demonstrate this scenario.

File –> New –> Office/SharePoint –> Apps and name it as ‘CreateSiteApp’.

image

In the SharePoint hosted app, I’d be making a call to the /_api/web/webinfos/add available in HostWeb to create a sub-site under HostWeb.

Open App.js file.

Copy and paste the following code. The following snippet leverages Cross Domain library of SharePoint 2013 to make

'use strict';

var context = SP.ClientContext.get_current();
var user = context.get_web().get_currentUser();
var HostWebUrl;
var AppWebUrl;



// This code runs when the DOM is ready and creates a context object which is needed
 to use the SharePoint object model
$(document).ready(function () {
    HostWebUrl =
                decodeURIComponent(
                    RetrieveQueryStringParameter("SPHostUrl")
            );
    AppWebUrl =
        decodeURIComponent(
            RetrieveQueryStringParameter("SPAppWebUrl")
    );

    var scriptbase = HostWebUrl + "/_layouts/15/";
    $.getScript(scriptbase + "SP.RequestExecutor.js", execCrossDomainRequest);


});

function RetrieveQueryStringParameter(ParamsforRetrieval) {
    var params =
        document.URL.split("?")[1].split("&");
    var strParams = "";
    for (var i = 0; i < params.length; i = i + 1) {
        var singleParam = params[i].split("=");
        if (singleParam[0] == ParamsforRetrieval)
            return singleParam[1];
    }
}


function execCrossDomainRequest() {

    var executor = new SP.RequestExecutor(AppWebUrl);
    executor.executeAsync(
        {
            url:  AppWebUrl +"/_api/web/webinfos/add",
            type: "POST",
            data: JSON.stringify(
                {
                    'parameters': {
                        '__metadata': { 'type': 'SP.WebInfoCreationInformation' },
                        'Url': 'SundarSite',
                        'Title': 'SundarSite',
                        'Description': 'Site created using REST',
                        'Language': 1033,
                        'WebTemplate': 'sts',
                        'UseUniquePermissions': false
                    }
                }
            ),
            headers: {
                "accept": "application/json; odata=verbose",
                "content-type": "application/json;odata=verbose",
                "content-length": 1028,
                "X-RequestDigest": $("#__REQUESTDIGEST").val()

            },
            success: successHandler,
            error: errorHandler
        }
        );




       

}

function successHandler(data) {
    document.getElementById("message").innerText =
        "Site Created Successfully";

}

function errorHandler(data, errorCode, errorMessage) {
    document.getElementById("message").innerText =
        "Could not complete cross-domain call " + errorMessage;
}

 Subscribe to my blog

How to access data in Host Web from SharePoint 2013 App

When we build SharePoint 2013 Apps, one of the common scenario that we will have is to read the data from Host Web.  This presents a classical Cross-Domain call scenario (where the fully-qualified domain for App Web and Host Web are different). By default, when we access the Host Web resources from App Web either using Java Script Model or Client Object Model, we’d get an access denied error. This fix for this scenario is to leverage javascript client-side solution in the form of (SP.RequestExecutor.JS) file. The cross domain libraries helps us to interact with more one domain in the SharePoint 2013 App through the Proxy. Let’s jump on to the steps.

Open Visual Studio 2013

File –> New –> Project –> Apps for SharePoint 2013 –> SharePoint hosted apps and name the App as ‘ReadHostWeb;

Set the site for debugging, in this case I’m using my Office 365 developer tenant ‘https://mytenant.sharepoint.com’

I’ve created an Announcement list in my Host Web and it has three Columns Title, Body and Version.

Open Default.aspx and paste the following snippet of code inside

 

<div id="ListFieldDiv"></div>

    <script type="text/javascript">
        var HostWebUrl;
        var AppWebUrl;
        var ListFieldHtml;

        // Load the required SharePoint libraries
        $(document).ready(function () {
            //Get the URI decoded URLs.
            HostWebUrl =
                decodeURIComponent(
                    RetrieveQueryStringParameter("SPHostUrl")
            );
            AppWebUrl =
                decodeURIComponent(
                    RetrieveQueryStringParameter("SPAppWebUrl")
            );

            
            var scriptbase = HostWebUrl + "/_layouts/15/";

            
            $.getScript(scriptbase + "SP.RequestExecutor.js", execCrossDomainRequest);
            
        });


        
        
        function execCrossDomainRequest() {
            
            var executor = new SP.RequestExecutor(AppWebUrl);

            
            executor.executeAsync(
    {
        url:
            AppWebUrl +
            "/_api/SP.AppContextSite(@target)/web/lists('5fabe2a3-7a5f-4444-ba3e-a684558d1e27')/fields?@target='" +
            HostWebUrl + "'",
        method: "GET",
        headers: { "Accept": "application/json; odata=verbose" },
        success: successHandler,
        error: errorHandler
    }
);

        }

        
        function successHandler(data) {

            var jsonObject = JSON.parse(data.body);
            var results = jsonObject.d.results;

            for (i = 0; i < results.length; i++)
            {
                if (results[i].Hidden == false) {

                    

                    if ((results[i].TypeDisplayName == "Single line of text") || (results[i].TypeDisplayName == "Multiple lines of text")) {

                        
                        if (results[i].Title == "undefined" || results[i].Title == "Version")
                        {


                        }
                        else
                        {
                            ListFieldHtml = ListFieldHtml + "<p>" + results[i].Title;

                        }

                        
                    }
                }
                

            }
            
            document.getElementById("ListFieldDiv").innerHTML = ListFieldHtml;

            
            


            
        }

       
        function errorHandler(data, errorCode, errorMessage) {
            document.getElementById("AnnouncementsDiv").innerText =
                "Could not complete cross-domain call " + errorMessage;
        }

       
        function RetrieveQueryStringParameter(ParamsforRetrieval) {
            var params =
                document.URL.split("?")[1].split("&");
            var strParams = "";
            for (var i = 0; i < params.length; i = i + 1) {
                var singleParam = params[i].split("=");
                if (singleParam[0] == ParamsforRetrieval)
                    return singleParam[1];
            }
        }
        </script>

 image

 Subscribe to my blog

Windows Azure Queue vs Service Bus Queuue

In Microsoft Azure, we have two implementations of Queues, Windows Azure Queues and Service Bus Queues. Both the Queues are the internally implemented using Message Queuing service offered on Windows Azure.

We should prefer Windows Azure Queues for the following scenarios:-

  • When the application needs to store over 5 GB worth of messages in a Queue and the life time of messages are shorter than 7 days
  • When server-side log is required for all transactions executed against Queues
  • When the application requires flexible leasing to process messages

We should prefer Azure Service Bus Queues for the following scenario :-

  • When the application requires full integration with .NET WCF
  • When message batches need to be published and consumed
  • When the message size handled by the application is between 64 KB and 256 KB
  • When the application requires “At most once” guaranteed delivery without the need to build additional infrastructure components
  • When the application requires First-In-First-Out (FIFO) delivery
  • When the Queue Size does not exceed 5 GB
  • When role-based access to Queue is required
  • When the application requires Automatic Duplicate detection
  • When the application Requires Atomicity and Transactional behavior when sending or receiving multiple messages from Queue
  • When the message retrieval does not require polling
  • When the Time-to-Live (TTL) characteristics of application-specific workload can exceed 7 day window

More detailed guidance, soft limits, Thresholds is given in http://msdn.microsoft.com/en-us/library/hh767287.aspx