2.4 Working with SharePoint Data
One of the most common tasks when
working with SharePoint is interacting with the various data sources
such as lists or document libraries. The great thing about SharePoint
is that you have a number of different options for interacting with
this data. For example, you have the Server Object Model, the
Client-Side Object Model (which has become more powerful since
SharePoint 2010), REST (or OData) services, SharePoint Services (which
ship out-of-the-box and cover a wide array of scenarios), and Business
Connectivity Services or BCS (which provide a rich set of APIs for
working with external data systems such as SAP, Microsoft Dynamics CRM,
or PeopleSoft).
Before you can do anything with SharePoint
programmatically, you need to establish a connection and context with
your SharePoint site. For the most part, this means using (or adding) a
reference in your project to Microsoft.SharePoint.dll or Microsoft.SharePoint.Client.dll.
With the appropriate references added to your project, you can then
begin to set the context and code within that context. For example, you
can set the context for a SharePoint site using the Server Object Model
by adding the Microsoft.SharePoint.dll to your project reference and then use the following using statements to wrap your code. In this code snippet, you set the site collection context and can either call the OpenWeb method on that site context, or use the RootWeb property to set the context of the SPSite object (that is, mySiteCollection). You would then add your code where the comment is marked.
using (SPSite mySiteCollection = new SPSite(mySiteUrl))
{
using (SPWeb mySPSite = mySiteCollection.RootWeb)
{
//Code here.
}
}
The SharePoint Client-Side Object Model is a way
to read and write data from SharePoint lists (and enables you to do it
through remote client apps). After adding the Microsoft.SharePoint.Client.Runtime.dll and Microsoft.SharePoint.Client.dll
references, you can use the following code to set the context with your
SharePoint site. When you’ve created your application code, you then
call the ExecuteQuery method to batch-process that code. The final statement (the Close method) disposes of the context from memory.
String mySiteUrl = "http://fabrikamhockey/acme";
ClientContext mySPSiteContext = new ClientContext(mySiteUrl);
//Code here.
mySPSiteContext.ExecuteQuery();
mySPSiteContext.Close();
You will find yourself using both the Server and
Client-Side Object Model in different scenarios; for server-side only
applications you can use the Server Object Model, and for remote client
or cloud-hosted apps you can use the SharePoint Client-Side Object
Model.
In SharePoint 2013, your options for interacting
with lists expand to include REST. To use REST, which supports full
create, read, update, and delete (CRUD) operations, you construct a
RESTful HTTP request using the Open Data Protocol (OData) standard.
This enables you to perform, for example, GET or POST operations against your SharePoint lists. The following REST URI retrieves all the items in the Customers list:
https://me.sharepoint.com/sites/sp/_api/web/lists/getbytitle('Customers')/items
The REST URI is quite versatile as well; you can
use it in JavaScript or .NET apps to interact with your list data. The
REST interface is efficient because it exposes all the SharePoint
entities and operations — some of which are not available in the other
APIs, and you can also manage the returned data through XML or through
JSON, so programming your client apps is flexible (you can use
client-side script or .NET apps against the REST URIs). The following
code illustrates how you can make a GET request that returns a JSON representation of all of your site’s lists by using jQuery:
$.ajax({
url:http://myspsite/_api/web/lists,
type: "GET",
contentType: "application/json;odata=verbose",
headers: {
"ACCEPT","application/json;odata=verbose",
"Authorization","Bearer" + accessToken
},
})
After you’ve obtained context with the SharePoint
object model, you can interact with data that resides on SharePoint.
For example, you can iterate over every list in SharePoint and get the
title of the list, you can retrieve views of specific lists, or you can
update properties or list items in lists programmatically. The
following code snippet shows the use of the Server Object Model to
obtain the SharePoint site context, but now you’re iterating through
the lists (see bolded code) on the SharePoint site and adding each list
title to a list box.
string mySiteUrl = "http://intranet.contoso.com/acme/";
string myListItemInfo = "";
using (SPSite mySiteCollection = new SPSite(mySiteUrl))
{
using (SPWeb mySPSite = mySiteCollection.RootWeb)
{
foreach (SPList mySPList in mySPSite.Lists)
{
myListItemInfo = mySPList.Title.ToString();
lstbxListTitles.Items.Add(myListItemInfo);
}
}
}
Again, you can do similar types of list
interaction by using the SharePoint Client-Side Object Model. The
following code snippet shows the setting of the site context again but
the bolded code retrieves a list called Inventory from SharePoint and
then loads it with a query to filter on the Salmon field.
String spURL = "http://fabrikamhockey/acme";
ClientContext spSiteContext = new ClientContext(spURL);
List myProducts = spSiteContext.Web.Lists.GetByTitle("Inventory");
spSiteContext.Load(spSiteContext.Web);
spSiteContext.Load(myProducts,
list => list.Fields.Where(field => field.Title == "Salmon"));
spSiteContext.ExecuteQuery();
spSiteContext.Close();
When updating list data, you can choose between
using the Server Object Model, CSOM, or REST services). One example is
to use the Server Object Model and then call the Update
method to update items on a SharePoint list. For example, the following
code takes the same site context code shown earlier, but instead of
iterating through the list, it now creates an instance of a specific
list and then adds a record to the list comprising two fields (Product_Name and Product_SKU). You can see the final call in this case is the Update method to add the new item (newListItem) to the SharePoint site.
using (SPSite mySPSite = new SPSite("http://fabrikamhockey/acme"))
{
using (SPWeb mySPWeb = mySPSite.OpenWeb())
{
SPList productsList = mySPWeb.Lists["Products"];
SPListItem newListItem = productsList.Items.Add();
newListItem["Product_Name"] = "Salmon";
newListItem["Product_SKU"] = "SLM-30989";
newListItem.Update();
}
}
Depending on what API you use, you might come
across the need to use Collaborative Application Markup Language (CAML)
constructs, which can get a bit hairy. In essence, CAML enables you to
build an XML-based query to return data from a SharePoint list. The
following illustrates a CAML query that returns all the results (up to
100). You can construct CAML queries across any of the SharePoint APIs.
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml('<View><RowLimit>100</RowLimit></View>');
this.collListItem = oList.getItems(camlQuery);
Beyond CAML queries, you can also use Language
Integrated Query (LINQ) statements to query SharePoint list data. LINQ
is a very effective way to query data, which is supported in SharePoint
2013. For example, the following LINQ statement retrieves the list item
(from a list represented through the myCustomerList object) where the customer name (represented as c) is Acme.
var customers =
from c in myCustomerList
where c == "Acme"
select c;
You’ll find many different ways to interact with
SharePoint lists. Becoming familiar with both a server-side and
client-side way to do this is best.
2.5 Creating Cloud-hosted Apps
A couple of things to
call out here, though, are that you have the flexibility to use the
CSOM and REST APIs within these apps. You must also manage OAuth (when
your app calls back into SharePoint) and app permissions, which beyond
moving to a more cloud-hosted model, is one of the key changes in
SharePoint 2013.
2.6 Creating Event Receivers
SharePoint supports a wide array of event receivers,
which are events that are triggered through a system or user action
such as updating a list or adding a new document to a document library.
You can create event receivers for a wide variety of objects such as
lists, list items, sites, and so on. For instance, suppose you want to
load external data as additional company metadata (such as company or
national holidays) when a user creates a new calendar item. This
requires a Web service call to load the data and an event receiver to
load the data when the user creates a new list item. You might also
want to log a transaction when certain lists are updated; this is
another effective way to use event receivers. You can also build event
receivers against feature activations or deactivations if you want.
This can be particularly handy when you need to clean up dependent
features or assemblies when a feature is activated or deactivated. The
event receiver can help remove any ancillary files or dependent Web
Parts from the Web Part gallery or the filesystem.
Event receivers are very easy to build and deploy
to SharePoint: you create event receivers using the Visual Studio Event
Receiver project or item template. Let’s go ahead and create a simple
event receiver in the following Try It Out to get you familiar with the
process.
TRY IT OUT: Creating a Simple Event Receiver
Event receivers are effective ways to
add triggers into your SharePoint solutions. To create a simple event
receiver, perform the following steps:
1. Open your SharePoint site and create a new list called TestList.
2. Open Visual Studio 2012 and click File ⇒ New Project, and select Event Receiver in the SharePoint 2013 project template folder.
3. Provide a name for your project (MyFirstEventReceiver) and click OK.
4. When
prompted in the wizard, select the List Item Events option under the
type of event receiver with which you want to associate your event,
select the Document Library option under the event source, and select
An item was added as the specific event (see Figure 15).
5. Click Finish.
6. In the SPEventReceiver.cs
file, added the following bolded code. This applies some of the code
discussed thus far and adds a new list item in another list.
using System;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Workflow;
namespace MyFirstEventReceiver.SPEventReceiver
{
public class SPEventReceiver : SPItemEventReceiver
{
public override void ItemAdded(SPItemEventProperties properties)
{
base.ItemAdded(properties);
logAnAnnouncementEvent(properties);
}
private void logAnAnnouncementEvent(SPItemEventProperties properties)
{
string eventTitle = properties.ListTitle;
string mySiteUrl = "http://w15-sp/";
using (SPSite mySiteCollection = new SPSite(mySiteUrl))
{
using (SPWeb mySPSite = mySiteCollection.RootWeb)
{
SPList mySPList = mySPSite.Lists["TestList"];
SPListItem newListItem = mySPList.Items.Add();
newListItem["Title"] =
"Event triggered from the following list: " + eventTitle;
newListItem.Update();
}
}
}
}
}
7. Click Build and then Deploy to build and deploy the event receiver project to your Share Point site.
8. Navigate to the Documents list and click Add Item to add a new document. When done, click OK. Figure 16 illustrates what this looks like.
9. Navigate to the TestList list, and you can see a new list item — see Figure 17.
How It Works
An event receiver is in essence a
custom DLL that gets deployed and called to the global assembly cache
(GAC) within SharePoint. Visual Studio, using the project template,
creates a feature that then references the custom assembly when the
action that triggers the event occurs. In this example, you added an
event that triggered whenever someone added an event to the
Announcements list. Specifically, the ItemAdded event was a default event handler that was created; it is here where you can add your code. For example, the bolded method (logAnAnnouncementEvent)
you added will have your event handler code in it (shown here). Note
that you’re passing the properties of the event, which you can use when
building out your event handler code.
public override void ItemAdding(SPItemEventProperties properties)
{
base.ItemAdding(properties);
logAnAnnouncementEvent(properties);
}
Within the logAnAnnouncementEvent page, you can see in the following that the one property used is the Title of the list, which is then stored in the eventTitle object.
private void logAnAnnouncementEvent(SPItemEventProperties properties)
{
string eventTitle = properties.Title;
string mySiteUrl = "http://intranet.contoso.com/";
using (SPSite mySiteCollection = new SPSite(mySiteUrl))
{
using (SPWeb mySPSite = mySiteCollection.RootWeb)
{
SPList mySPList = mySPSite.Lists["TestList"];
SPListItem newListItem = mySPList.Items.Add();
newListItem["Title"] = "Event triggered from the following list:
" + eventTitle;
newListItem.Update();
}
}
}
Most of the other code will now be
familiar to you because you’ve already seen how you add an item to a
list. As you explore event receivers, be sure to try out some other
types of events that are more complex and involve other parts of the
SharePoint site — or external data that you can leverage within your
SharePoint site.