Read the intro to this series here.
Ok, so by this stage I hope you have read Part 1 on Authentication. Understanding how to authenticate with SharePoint from a mobile applications is a critical step before you can interact with it to get data in and out of it etc…
Ok, I have authenticated successfully … now what?
Generally most people want to go and get some data from SharePoint, like a set of data from a list or library for example. SharePoint provides a plethora of APIs to work with data. Options include SOAP Web Services, RSS feeds, client side object model, or the fronting the service side object model with a custom WCF web service of the link. Or finally the in built REST/OData endpoints.
The REST/OData endpoints, in my opinion, are the best and most flexible choice for most mobile scenarios. Why:
- Simple HTTP calls, easy from every mobile platform
- JSON or XML responses
- Read and Write operations
- Easy filtering and query capabilities
“It’s what all the cool kids are doing!”
A lot of services like twitter and Facebook etc. provide REST APIs so generally it’s a well accepted method for working with a service from a mobile platform. There is a lot of community support for working with these kinds of services from phone platforms too.
On Windows Phone for example there are two libraries I use in nearly all my mobile projects:
What do the SharePoint REST services offer?
SharePoints REST services follow (mostly) the OData protocol (odata.org). I say mostly because there are some differences (what would a standard be without a few differences to keep us on our toes!) that I will highlight later on.
SharePoint 2010 provides REST/OData endpoints at the /_vti_bin/ListData.svc url.
e.g. http://MySharePointServer/SiteName/_vti_bin/ListData.svc
There are quite a few ways to get the data you want. The simplest is just retrieving all the items from a list.
For example if we had a SharePoint list called “Tasks” then we could issue a GET query for the items in that list by calling:
http://MySharePointServer/SiteName/_vti_bin/ListData.svc/Tasks
As I said above, there are quite a few ways to query for data etc… The best place to read about all those is here: http://www.odata.org/documentation/uri-conventions
However, I will mention a couple of good ones to get you started. In particular $filter, $select
Get a single Task:
/_vti_bin/ListData.svc/Tasks(1) <- where 1 is the id of the task
Filter for tasks with a title that starts with “Remember”:
/_vti_bin/ListData.svc/Tasks?$filter=startswith(Title,’Remember’)
Note: startswith is just one operation. you can find others in the documentation here.
Just get the properties of a object that you want:
/_vti_bin/ListData.svc/Tasks?$select=Title
In this example I just wanted the Title of the Task, not all the other properties. Being able to select just the data you want is really important in mobile apps given you want to keep the data payloads to the absolute minimum. Selecting just the data you want really helps this.
I am making the request but I am getting XML back. How do I request JSON?
JSON (JavaScript Object Notation) is a lightweight data format that is super easy for JavaScript to parse and work with & fortunately for Mobile developers has a lot of community support (like JSON.Net) for dealing with it in .Net applications like Windows Phone. In fact there is good support for it across the major mobile platforms.
Lightweight is a critical word here. Like I said above, its really critical to keep your data payloads small and fast. Another way to assist with this is to use JSON. It’s lighter than the XML equivalent & it compresses well too. In mobile apps some people pay for data by the MB, so not only does it make it faster, but cheaper to use your app.
To request JSON data responses from SharePoint’s REST services you need to set the HTTP Accept header to “application/json”.
On Windows Phone using the HttpWebRequest object you do that in one line of code like this:
request.Accept = @”application/json”;
Once you get the JSON response you can use JSON.Net to deserialize it into strongly typed objects like so:
TasksResult tasks = JsonConvert.DeserializeObject<TasksResult>(responseString);
Note: You need to generate your objects for deserialization. You can hand craft those if you like or use a tool like http://json2csharp.com/ to help build your classes from a sample JSON response.
What about other stuff I can do via the REST services?
SharePoint not only supports reading of data via REST/OData, but also writing. Instead of issuing a GET request to query for data we can use the some of the other HTTP verbs to write data.
Here is a list of the verbs:
- POST – Create
- GET – Retrieve
- PUT – Update (all properties)
- DELETE – Delete
- MERGE – Update (only select properties)
Most of these are fairly self explanatory … however the PUT & MERGE are pretty similar. The difference is that with PUT you have to send your updated object with ALL of the properties regardless of if you want to update them or not. Whereas MERGE allows you to only specify the properties you want to update.
So for example, if you wanted to Create a new Task in the Tasks list you would send a POST HTTP request to:
POST to http://MySharePointServer/SiteName/_vti_bin/ListData.svc/Tasks
With the body of the POST being the JSON representation of your new Task. Again you can use JSON.Net to assist with desterilizing your Task object to JSON like this:
var json = JsonConvert.SerializeObject(myNewTaskObject);
To update an existing task you would send a MERGE request to:
http://MySharePointServer/SiteName/_vti_bin/ListData.svc/Tasks(X)
X = the ID of the task you want to update. Along with the body of the request being the JSON representation of the Task. You can omit the fields you don’t want to update with a MERGE to keep the payload size down.
How do I deal with someone else updating the list between when I get the list data and updating it?
This is called concurrency management and SharePoint gives you some help here …if you want it 🙂
What you really want to do is say .. I want to update this list item, but only if it has not changed since I retrieved it.
To do this SharePoint issues ETags as properties on objects when you retrieve them, which are effectively sequence numbers that change when an item is updated. For example in an XML response you would see something that looks like this:
<entry m:ETag="W/"2"">
So when you do a PUT, MERGE or DELETE on an item you need to attach this ETag that you received. This basically says to SharePoint, only let me do this update only if the ETag hasn’t changed.
You add this to your request by adding another HTTP Header called “If-Match”. For more information on the If-Match HTTP header have a read of section “14.24 If-Match” in the HTTP RFC here: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
e.g. header values:
If-Match: "W/”2”"
If-Match: * <= This says overwrite it regardless
If your ETag doesn’t match SharePoint will throw an error back in the response. Your code should deal with this situation! Typical options would be to offer the user the ability to merge the conflicts, overwrite regardless or discard their changes. There is no one right answer in this situation & it will depend on your business rules for your app what you will need to do.
Summary
SharePoint offers a very mobile friendly API with the REST/OData endpoints. Using these + requesting JSON data responses gives you a combination that has great community library support of creating and parsing requests/responses as well as being platform independent. If offers CRUD (Create, Read, Update & Delete) operations on list and library data so covers the bases there.
+ REST/JSON are what all the cool kids are doing on services like Twitter/Facebook … so you won’t sour their SharePoint experience too much by trying to force them to use the long in the tooth SOAP web services instead 🙂
In the sample project you can find an example of requesting a list of Tasks from the default Task list in a team site via the REST with JSON responses. Check MainPage.xaml.cs in the LoadTasks() method.
DOWNLOAD Sample
In the next post in the series I will discuss some options on how you can make your SharePoint data available to your mobile apps when you leave the office via Azure and Service Bus.
Thanks,
-Chris.