Connecting to the SharePoint 2013 REST API from C#

Today I was updating an internal application we use for grabbing lots of Terminology data from SharePoint lists, and exporting it as TBX files for import into CAT tools etc.

This was required as the SharePoint on which it was hosted previously was upgraded from 2010 to 2013.

A small job I thought.

Then I discovered the the ASMX Web Service in SharePoint I used to grab the data previously, are deprecated in SharePoint 2013, probably not a surprise to anyone in the know, but SharePoint happens to be one of my pet hates, so development of it is not something that I tend to keep up to date with.

Anyway, I had to re-jig our application to use the SharePoint REST API, and I thought I’d provide the code here for connecting, as it look a little bit of figuring out.

The below (after you fill in your SharePoint URL, username, password, domain, and name of the list you want to extract data from), will connect and pull back the list contents to an XmlDocument object that you can parse.

XmlNamespaceManager xmlnspm = new XmlNamespaceManager(new NameTable());
Uri sharepointUrl = new Uri("SHAREPOINT URL);

xmlnspm.AddNamespace("atom", "http://www.w3.org/2005/Atom");
xmlnspm.AddNamespace("d", "http://schemas.microsoft.com/ado/2007/08/dataservices");
xmlnspm.AddNamespace("m", "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");

NetworkCredential cred = new System.Net.NetworkCredential("USERNAME", "PASSWORD", "DOMAIN");

HttpWebRequest listRequest = (HttpWebRequest)HttpWebRequest.Create(sharepointUrl.ToString() + "_api/lists/getByTitle('" + "LIST NAME" + "')/items");
listRequest.Method = "GET";
listRequest.Accept = "application/atom+xml";
listRequest.ContentType = "application/atom+xml;type=entry";

listRequest.Credentials = cred;
HttpWebResponse listResponse = (HttpWebResponse)listRequest.GetResponse();
StreamReader listReader = new StreamReader(listResponse.GetResponseStream());
XmlDocument listXml = new XmlDocument();

listXml.LoadXml(listReader.ReadToEnd());

SQL – Alter a database user’s password via a query

Here’s some handy SQL to alter the login of an existing user via a query. I recently lost my login to one of the databases I use for a project (OK, I didn’t lose it, I forgot it). Luckily I had another account I could login to the database with via SQL Server Management Studio, and execute the below query to reset the password of the one that I forgot.

This got me out of a bind:

GO
ALTER LOGIN [login_name] WITH DEFAULT_DATABASE=[database_name]
GO
USE [database_name]
GO
ALTER LOGIN [login_name] WITH PASSWORD=N'new_password' MUST_CHANGE
GO

Refactoring horrible nested if-else statements

I wrote this at some point this week, I was looking back at it tonight and released how truly awful it looks:

if(filePath.Contains(".CSS"))
    return true;
else
    return false;
else if(filePath.Contains(".JS"))
    return true;
else
    return false;
else if(filePath.Contains("_STR"))
    return true;
else
    return false;
else if(filePath.Contains(".VBS"))
    return true;
else
    return false;
else if(filePath.Contains(".HTM"))
    return true;
else
    return false;
else if(filePath.Contains(".BMP"))
    return true;
else
    return false;
else if(filePath.Contains("GIF"))
    return true;
else
    return false;

Terrible huh? What was I thinking?

How much better does this look:


bool copyFile;

copyFile = (filePath.Contains(".CSS"))      ? true:
               (filePath.Contains(".JS"))   ? true:
               (filePath.Contains("_STR"))  ? true:
               (filePath.Contains(".VBS"))  ? true:
               (filePath.Contains(".HTM"))  ? true:
               (filePath.Contains(".BMP"))  ? true:
               (filePath.Contains("GIF"))   ? true:
                                              false;
return copyFile;

I like it, impressed with that one for a Friday.

WPF – Binding Data in an XML file to a ComboBox

Some things in WPF are very different from Windows Forms programming. Lately, I’ve been working on my first real UI in which I’ve used WPF over Windows Forms. Using XAML takes a little bit of getting used to, but I’m finding that I have a lot more control over the UI, along with the obvious advantage of seperating the UI presentation from the actual application logic.

Just the other day I needed to create a ComboBox control on a section of my UI, the items in which would need to be loaded from an XML file at runtime. The XML file was to be included as a resource.

The XML file looked something like this:






...

I wanted the ‘name’ attribute from each Language node to be bound to my ComboBox. In order to do this, first we need to define the XML file as a resource in our XAML:





...
...

Then, we just need to add the ItemsSource, SelectedValuePath, and DisplayMemberPath to the ComboBox XAML, specifying the resource we declared earlier, and the attribute that we want to bind:




Note the ‘SelectedItem’ can be set as well from the XAML, It’s set to ‘Arabic’ in the above example.

Windows Phone 7 – Check if first run

Many of the applications I’ve been looking at developing during my Windows Phone 7 endeavours have a common requirement – the ability to check if this is the first run of the application. For example, if you are designing an application that will access a service like Twitter or Facebook, you’ll need to gather the users login details in order for your application to function.

For example, on the first run of the application, we’ll want to display a login dialog, gather the users information and store it. We can use the isolated storage facility on Windows Phone 7 devices to store this information. If you’re unfamiliar with isolated storage, check out my previous post here.

Step 1 – Store a value to track if this is the first run

I added this code to the ‘Application_Launching’ function. This function is called each time your application is launched.


// Code to execute when the application is launching (eg, from Start)
// This code will not execute when the application is reactivated
private void Application_Launching(object sender, LaunchingEventArgs e)
{
// Set if this is the first run of the application or not
if (!settings.Contains("firstRun"))
{
settings.Add("firstRun", (bool)true);
}
else
{
settings["firstRun"] = (bool)false;
}
}

Step 2 – Intercept navigation to your main page, redirect if necessery

Next, we need to create an event handler to intercept any navigation the your main page, and redirect to your ‘first run’ page (login or whatever) if necessery.

First we check if we’re navigating to our main page, if we’re not the function just returns and navigation proceeds as normal. If we are, we’ll ensure that if it’s the first run of the application, the user will be redirected to a login page etc.


///

/// Event handler to intercept MainPage navigation
///

/// the frame /// navigation args void RootFrame_Navigating(object sender, NavigatingCancelEventArgs e)
{
// Only care about MainPage
if (e.Uri.ToString().Contains("/MainPage.xaml") != true)
{
return;
}

// Check if this is the first run of the application
if ((bool)settings["firstRun"])
{
e.Cancel = true;
RootFrame.Dispatcher.BeginInvoke(delegate
{
RootFrame.Navigate(new Uri("/FirstRun.xaml", UriKind.Relative));
settings["firstRun"] = (bool)false;
});
}
else
{
RootFrame.Dispatcher.BeginInvoke(delegate
{
RootFrame.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
});
}
}

Step 3 – Ensure the event handler is called when navigation occurs

Finally, we need ensure that the event handler we created in step 2 above is actually called when any navigation occurs. To accomplish this, all we need to do is add the following code in the constructor of the ‘App.xaml.cs’ file:

// Add this code to the constructor in App.xaml.cs

// Route the user to the login screen if it's the first run of the application
RootFrame.Navigating += new NavigatingCancelEventHandler(RootFrame_Navigating);

That’s pretty much it, I’ve successfully used the above mechanism in two different applications, hope this saves you some time!

Windows Phone 7 – Storing & Retrieving Information

I’m planning on doing a series of posts called ‘2 Minute Tutorials’. I always get frustrated when searching for information on the Internet. Sometimes, I just want a simple explanation, and a code example that I can utilize immediately. This is what I hope to provide in this series of posts, which will be mostly related to Windows Phone 7, C#, and C++.

In this particular installment, I’m going to take you through the process of storing and retrieving information on the Windows Phone 7 platform – a certain requirment should you intend developing a WP7 application. You can store information on the phones local file system quite easily. This may be required for saving such things as user information like usernames and passwords to services such as Twitter, or application specific preferences such as a preferred language or orientation.

This functionality is provided by the IsolatedStorageSettings class contained in the System.IO.IsolatedStorage namespace. It’s ‘isolated’, because it can only be accessed by your application, not by any others. If you need to share information between applications, you’ll need to store it on the web somewhere – this offers local, isolated storage only.

IsolatedStorageSettings allows you to store name/value pairs in a dictionary. This data will always be there, even after powering off the phone. It will remain in the file system until you either remove it, or you uninstall the application to which it belongs.

Here’s an example of storing an item called ‘username’:

using System.IO.IsolatedStorage;
...
IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
settings.Add("username", "jimmy");

Simple. It’s just as easy to retrieve the data again:

string username = (string) settings['username'];

Some important things to remember:

  • Your application will throw an exception if you try to retrieve a value that is not present so you should always handle this case.
  • You can save anything, even Objects.
  • You have to explicitly cast your data when you retrieve it.

That’s it. It’s that simple to store and retrieve information on the local file system of a device running Windows Phone 7.

See here for the MSDN documention on IsolatedStorageSettings.

LINQ to XML – What I’ve been missing

Ok. You may laugh. I’ve just today used LINQ for the first time to parse an XML file, and I’m seriously blown away at how easy it was. I’m a little embarrassed, since LINQ has been available since .NET 3.5 was released around November 2007.

If you are like I was, (LINQ-less!!), I’ll give a brief introduction here. LINQ (Language INtegrated Query), is a component that adds native data querying capabilities to .NET languages. It can be used to read, parse and write XML files (and also SQL, which I may cover in a future post). Take a look at the example below to see how easy it is to use this technique to read data from an XML file.

Reading data from an XML file is a very common scenario. I always used .ini file as configuration files for any applications I wrote, but .NET doesn’t provide any built in support for .ini, and hence wants you to use XML.

Consider the following XML file:

In order to read this using LINQ to XML, you need to ensure you have specifed the correct header files:


using System.Linq;
using System.Xml.Linq;

Now for the easy part, here’s the code to read data from the XML file, and print out the values to the console:


XDocument xmlDoc = XDocument.Load(@"example.xml");
var servers = from server in xmlDoc.Descendants("server")
select new
{
     Name = server.Element("name").Value,
     IP = server.Element("ip").Value,
     Owner = server.Element("owner").Value,
};


foreach (var server in servers)
{
     Console.WriteLine("Server Name: " + server.Name);
     Console.WriteLine("Server IP: " + server.IP);
     Console.WriteLine("Server Owner: " + server.Owner);
}

Easy huh? The line beginning with ‘var servers=…‘ may look strange to you if you’ve never seen it before, (it did to me). This is an anonymous type declaration. If you’ve never heard of anonymous types in C#, MSDN has some great documentation here.

Happy coding.