Chapter 5. Server Object Model

As you learned in Chapter 1 Microsoft SharePoint 2013 is based directly on Microsoft .NET and Microsoft ASP.NET. Not surprisingly, one of the main tools that you will use to develop server-side solutions interacting with the SharePoint engine is the .NET object model offered by the SharePoint infrastructure. Called the Server Object Model, it is a set of namespaces and classes divided into several .NET assemblies. You can reference and use it in any kind of .NET solution that will run on a SharePoint server. In fact, the Server Object Model has some dependencies that are satisfied only on servers in a SharePoint farm, so you cannot use it in client-side solutions, SharePoint apps, remote event receivers, or anything else that is not running on a SharePoint server.

Thus, the Server Object Model is a good choice only for code-based solutions running on a SharePoint server. These are typically deployed through a farm solution or a sandboxed solution. You cannot create farm solutions at all in Microsoft Office 365, and starting with SharePoint 2013, you should also create SharePoint apps, rather than code-based sandboxed solutions.

If you are writing a software solution that interacts with SharePoint but does not run on a SharePoint server, you can use the Client Object Model, the new REST (Representational State Transfer) API, or OData (Open Data Protocol). For more information on these, see Part II and Part III

The key point of the Server Object Model is that you can use it to do in code everything (and more) that you can do with the SharePoint UI, whether through the browser, using the command-line tools, or with Windows PowerShell.

This chapter shows you how to use the major classes of the Server Object Model by examining their main members. You won’t find a complete reference for the entire object model here, because it contains thousands of types—an encyclopedia would probably be insufficient.

More Info

If you are looking for a complete reference of all the types in the SharePoint Server Object Model, see the “.NET server API reference for SharePoint 2013” page on MSDN, at http://msdn.microsoft.com/en-us/library/jj193058.aspx.

Startup environment

Before you begin working with the Server Object Model, and the examples in this chapter in particular, you need to make a few preparations. Because the UI is not a focus of this chapter, the code samples shown here mainly use a console application, which will need to execute on a SharePoint server. Consider that in real-life development, using a console application or a PowerShell script for testing code using the Server Object Model often speeds up the development by skipping the deployment phase. (Throughout the book, however, you will see the Server Object Model in action within SharePoint solutions as well.) To test the code samples in this chapter, you need to create a new Console project in Microsoft Visual Studio 2012. Next, make sure that the Target Framework setting on the Application tab of the project is set to .NET Framework 4.5. Because Microsoft SharePoint 2013 works on 64-bit machines only, specify x64 for the Platform Target setting on the Build tab of the project. Lastly, you need to reference some of the SharePoint Server Object Model assemblies, including Microsoft.SharePoint.dll, which is the main Server Object Model assembly. You can find it, along with many of the other assemblies, in the SharePoint15_RootISAPI folder, as well as in standard .NET references in Visual Studio.

Note

SharePoint15_Root represents the SharePoint root folder, which usually is located in C:Program FilesCommon FilesMicrosoft SharedWeb Server Extensions15.

Objects hierarchy

All the main types of the Server Object Model are defined in namespaces that start with Microsoft.SharePoint.* or Microsoft.Office.*, and in general have a type name that begins with SP, which stands for SharePoint. For example, the type that represents a user is named SPUser and belongs to the namespace Microsoft.SharePoint. The type that represents a SharePoint site, also defined in that namespace, is named SPWeb. Figure 5-1 shows some of the main classes and their hierarchical organization in the Server Object Model.

A diagram depicting the main types of the Server Object Model. At the top of the hierarchy is SPFarm, which contains a collection of SPService instances. One of these is the SPWebApplication type, which contains SPSite instances. Each SPSite instance is made of one or more SPWeb instances. Every SPWeb instance is parent of some SPList instances.

Figure 5-1. The hierarchy of the main types of the SharePoint Server Object Model.

The sections that follow explore the main types of the Server Object Model, briefly discussing their key members and showing some quick code samples. Later in the chapter, you will learn how to take advantage of these types in everyday solutions by working through some examples.

SPFarm, SPServer, SPService, and SPWebApplication

The first and main object of the Server Object Model is the SPFarm class, which represents a reference to an entire SharePoint server farm. This class belongs to the Microsoft.SharePoint.Administration namespace. You can use it to create a fresh new farm from scratch, or you can connect to an existing farm. To create a new farm, you need to invoke one of the many overloads of the public static Create factory method. To connect to an existing farm (the most common scenario), you provide a SQL Server connection string and the farm’s secret passphrase to the public static Open method, which has the following signature:

public static SPFarm Open(SqlConnectionStringBuilder connectionString, SecureString passphrase)

The connection string corresponds to the farm configuration database that is defined while configuring the farm using the SharePoint 2013 Products Configuration Wizard or PowerShell. You can also find it in the system registry at HKLMSoftwareMicrosoftShared ToolsWeb Server Extensions15.0SecureConfigDBdsn. Alternatively, you can connect directly to a local farm using the static property SPFarm.Local.

Important

By default, the SharePoint Server Object Model impersonates the current user. Thus, whenever you create an instance of an SP* type without providing any specific set of user credentials, your code impersonates the user running the process or the web request when you invoke the Server Object Model from a webpage.

After obtaining an instance of SPFarm, you can browse and manage servers and services that belong to that farm. For example, you can browse the Servers collection to enumerate all the physical servers that belong to the farm as objects of type SPServer. You can browse the Services property, which has the type SPServiceCollection and contains different kinds of services—all sharing a common base class of type SPService. You can examine all the Windows services, which are objects of type SPWindowsService, or you can access the web services, which are of type SPWebService. Every web service is composed of one or more web applications, each with the type SPWebApplication. Browsing objects in the local farm shows a code example that browses for all these kinds of objects in the local farm. Note that you should execute this (and the following) code excerpt in a project that references the Microsoft.SharePoint.dll assembly, and you should also provide a using statement for Microsoft.SharePoint, as well as for Microsoft.SharePoint.Administration.

In real life, you do not need to edit a farm’s configuration on a daily basis; however, it is important to know that the Server Object Model enables you to edit it should the need arise. Moreover, sometimes it’s useful to begin browsing your farm topology from the root node (SPFarm) so you can explore the site collections and websites in greater detail. You can also execute the same kind of code from a PowerShell script, if you prefer.

SPSite and SPWeb

SPSite and SPWeb are fundamental types in the Server Object Model. They represent a site collection and a site, respectively. From a SharePoint perspective, a website (SPWeb) is just a child of a collection of one or more sites (SPSite). As you will see later in this chapter, these classes are the basis for many typical operations in your solutions. Every time you need to access the content of a SharePoint site, you will need to reference its parent SPSite object (the site collection the site belongs to), and then open the corresponding SPWeb instance. To access an SPSite instance, you can create it using one of the available constructors, or you can obtain a reference to it through its parent SPWebApplication instance. Here are the constructors provided for building an SPSite instance:

public SPSite(Guid id);
public SPSite(string requestUrl);
public SPSite(Guid id, SPUrlZone zone);
public SPSite(Guid id, SPUserToken userToken);
public SPSite(string requestUrl, SPUserToken userToken);
public SPSite(Guid id, SPUrlZone zone, SPUserToken userToken);

Using the appropriate constructor, you can reference a site collection by its unique ID, which is a globally unique identifier (GUID), or with a URL that corresponds to a resource published by the site collection. Some of these six overloads of the constructor let you access the site by using a specific zone from the SPUrlZone enumeration, the definition of which is shown in the following:

public enum SPUrlZone {
    Default,
    Intranet,
    Internet,
    Custom,
    Extranet
}

These values correspond to the zones that you can create using the SharePoint administrative tools. Other SPSite constructors accept an SPUserToken instance. The SPUserToken class represents a token for a valid SharePoint user. When you create an SPSite instance using such a token, you can impersonate the user who owns that token rather than the current user. You can import an SPUserToken instance from a previously exported array of bytes, or you can create one from an object that implements the generic System.Security.Principal.IIdentity interface. You would, for example, take advantage of these constructor overloads to execute code on behalf of another user, probably one with elevated privileges.

More Info

In the SharePoint Server Object Model, starting from SPSite and moving down to the SPWeb, SPList, and SPListItem (refer to Figure 5-1), almost every object instance has a unique and identifying ID property, which can be a GUID or an integer. You should become accustomed to the idea of having an ID to uniquely reference each of these types. In general, you can also use URLs or titles to reference items, but using the unique ID helps to prevent errors.

Browsing for SPSite and SPWeb objects of an object of type SPWebApplication shows a code excerpt that browses all the SPSite and SPWeb instances in a set of SPWebApplication objects. The webService variable in the excerpt references an instance of an SPWebService object, which can be retrieved using the code illustrated in Browsing objects in the local farm.

The example in Getting a reference to an SPSite object using its public URL shows how to obtain a reference to an SPSite object using its public URL.

After you have a reference to an SPSite instance, you can browse for the sites contained in the collection, or you can change the configuration of the site collection itself. Table 5-1 lists the main members of the SPSite type, which you will probably use often in real projects, along with a brief description of each member.

Table 5-1. Some of the members of the SPSite type

Member name

Description

AllowUnsafeUpdates

Property to get or set whether to accept updates via HTTP GET or without validating data security of messages sent via HTTP POST. Setting this property to a value of true reduces the security of the website. For further details on this, read the “Common and best practices” section later in the chapter.

AllWebs

Collection property that holds references to all the websites contained in the current site collection.

CheckForPermissions

Method that checks the permissions for a given set of rights and throws an exception if the check fails.

Delete

Method (along with some overloads) that deletes the current site collection from the parent web application.

DoesUserHavePermissions

Method that’s almost the same as CheckForPermissions, but returns a Boolean result rather than throwing an exception when the check fails.

EventReceivers

Collection property that contains references to the event receivers configured for the current site collection. Those are the event receivers installed on the SharePoint server, not the remote event receivers that are discussed in Chapter 10

Features

Collection property that you can use to enumerate the features associated with the current site collection. For more information about features, refer to Chapter 4

GetCustomListTemplates

Method that returns the list of custom list templates for a specific website in the current site collection.

GetCustomWebTemplates

Method that returns the list of custom website templates available in the current site collection, based on a specific locale ID.

GetEffectiveRightsForAcl

Method that returns the effective rights of the current user for a specified target access control list (ACL).

GetRecycleBinItems

Method that lets you query the current contents of the Recycle Bin.

GetRecycleBinStatistics

Method that lets you obtain the size and the number of items in the Recycle Bin.

ID

Read-only property that represents the ID of the current site collection.

IISAllowsAnonymous

Read-only Boolean property that indicates whether anonymous access is configured in Internet Information Services (IIS) for the web application containing the current site collection.

Impersonating

Read-only Boolean property that returns true when the current instance of SPSite has been created by impersonating a third-party identity using an SPUserToken object instance.

OpenWeb

Method (and its overloads) that returns an SPWeb instance corresponding to a specific website contained in the current site collection.

ReadLocked

Property to get or set the ReadLocked status of the current site collection. When TRUE, the site will not be accessible via the Server Object Model or remote procedure call (RPC), and will return an HTTP 403 (FORBIDDEN) status code to any web browser request. To set this value, you need global administrative rights. For example, you can use this property to suspend service for a customer with a payment overdue. In that scenario, you should set the LockIssue property before setting the ReadLocked property to true.

ReadOnly

Property to get or set the read-only status for the contents of the current site collection. Setting this property to true also sets the WriteLocked property to true.

RecycleBin

Collection property by which you can enumerate the items currently contained in the Recycle Bin of the current site collection.

RootWeb

Property that returns a reference to the root website of the current site collection.

Solutions

Collection property that supports enumerating the sandboxed solutions associated with the current site collection.

Url

Read-only property that returns the full URL to the root website of the current site collection.

WorkflowManager

Read-only property that gives you access to the object managing workflow templates and instances in the current site collection. This property relates to the legacy workflow engine provided for backward compatibility with SharePoint 2010. For further details about workflows, see Part V

WriteLocked

Boolean property that’s similar to ReadLocked, but affects write access only.

Zone

Property that returns the zone used to construct the current SPSite instance.

An SPSite object is required to obtain access to an SPWeb instance. In fact, the SPWeb class does not have a public constructor. The only way to obtain a reference to a site is through its parent SPSite object, although you can get access to the current website using the SPControl and SPContext types, which will be discussed later, in the “SPControl and SPContext” section. The SPSite class provides the OpenWeb method (see Table 5-1) for this purpose. Getting a reference to an SPWeb instance through its parent SPSite object shows an example of accessing a specific website by using its parent site collection.

Getting a reference to an SPWeb instance through its parent SPSite object uses the SPSite.OpenWeb method, which has the following overloads:

public SPWeb OpenWeb();
public SPWeb OpenWeb(Guid gWebId);
public SPWeb OpenWeb(string strUrl);
public SPWeb OpenWeb(string strUrl, bool requireExactUrl);
public SPWeb OpenWeb(string strUrl, SPSiteOpenWebOptions options);

The first overload opens the lowest-level website, as defined by the URL provided to the constructor of the current site collection. For example, if you created the SPSite instance using the root site URL, you would get a reference to the root website. In contrast, if you created the SPSite instance using a child website URL, you would get a reference to that website. The second overload opens the website using its unique ID. The last three overloads accept the relative URL of the website, which must be exact for the last overload if the requireExactUrl argument is true. In the last overload, you have an option of type SPSiteOpenWebOptions, which allows you the choice of initializing a navigation cache.

You can use an SPWeb reference to navigate the contents of the site or simply to read or change its configuration. You will learn how to manage site contents later in this chapter. Table 5-2 lists some of the main members of the SPWeb type.

Table 5-2. Some of the members of the SPWeb type

Member name

Description

AllowUnsafeUpdates

Property to get or set whether to accept updates via HTTP GET or without validating data security of messages sent via HTTP POST. Setting this property to a value of true reduces the security of the website. For further details on this, read the “Common and best practices” section later in the chapter.

AllUsers

Collection property that holds references to all the users who are members of the website, or who have browsed to the site as authenticated members of a domain group in the site. For further details about users and groups, see Chapter 19

AppDatabaseName

Read-only property providing the name of the app database for the current web site.

AppDatabaseServerReferenceId

Read-only property to get the ID (GUID) of the server where the app database is located.

CheckPermissions

Method that checks whether the current user has a specific set of permissions. Throws an exception in case of failure.

ContentTypes

Collection property for enumerating all the content types in the website.

Delete

Method that deletes the current website.

EventReceivers

Collection property that holds references to all the event receivers of the website. Those are the event receivers installed on the SharePoint server, not the remote event receivers that are discussed in Chapter 10.

Features

Collection property by which you can enumerate the features associated with the current website. For more information, see Chapter 4.

Fields

Collection property by which you can enumerate all the site columns of the website.

Files

Collection property that holds references to all the files in the root directory of the website.

Folders

Collection property that holds references to all the first-level folders of the website.

GetFile

Method that returns a file, based on its GUID or URL.

GetFolder

Method that returns a folder, based on its GUID or URL.

GetRecycleBinItems

Method that allows querying the current contents of the Recycle Bin.

GetSiteData

Method that queries for list items across multiple lists and multiple SPWeb instances within a site collection. It returns a object of type System.Data.DataTable of ADO.NET.

GetUserEffectivePermissions

Method that returns the effective permissions for a specified username.

Groups

Collection property by which you can enumerate all the groups of the website. For more information about users and groups, see Chapter 19.

ID

Read-only property that represents the ID of the current website.

Lists

Collection property by which you can enumerate all the lists of the website.

RecycleBin

Collection property by which you can enumerate the items currently in the Recycle Bin of the current website.

Site

Property for referencing the parent site collection.

SiteUsers

Collection property that holds references to all the users of the current site collection. For more information about users and groups, see Chapter 19.

Title

Property to get or set the title of the website.

Update

Method that saves any changes applied to the website to the database.

Users

Collection property containing references to all the users with explicitly assigned permissions in the current website. For more information about users and groups, see Chapter 19.

One of the most interesting members of this type is the Update method. While working with the Server Object Model, you are reading and changing an in-memory representation of the current object. Thus, any changes you make will not be applied to the database unless you explicitly request the object to persist its state using the Update method. Of course, if you change an in-memory SPWeb instance and do not invoke the Update method, your changes will be lost. This behavior is common for many types in the Server Object Model, including SPWeb, SPList, and SPListItem. Additionally, remember that in a typical SharePoint farm, the database server runs on a separate server, which is not the web front end or the application server where your code will run. Thus, saving the state of an object and invoking the Update method requires crossing the wire.

Modifying the title of an instance of SPWeb shows an example that modifies the Title property of the current website, and then invokes the Update method to confirm the action.

SPList and SPListItem

Quite often, you will open an SPSite instance and one of its child SPWeb instances to gain access to the contents of one or more lists. The Server Object Model offers two types that target the concept of SharePoint lists and list items: SPList and SPListItem. SPList corresponds to a single list instance, whether that is a list of items or a document library. SPListItem defines a reference to a specific item of a list. In general, you open the list to extract one or more items, and then work with those items. Browsing the items contained in an SPList instance of an object of type SPWeb shows an example that obtains a reference to a list and then browses its items.

Browsing the items contained in an SPList instance of an object of type SPWeb extracts an SPList object by using the Lists indexer of the current SPWeb instance, which uses the list Title property as a key. Then it enumerates the contents of the Items collection property of the list instance. The SPList type offers a rich set of members. Table 5-3 shows some of the more important members.

Table 5-3. Some of the members of the SPList type

Member name

Description

AddItem

Method that creates a new empty item in the current list. Once it’s created, you will need to compile the fields of that item according to the validation constraints of the list.

BreakRoleInheritance

Method that breaks inheritance of role assignments for the current list and eventually copies role assignments from the parent website.

CheckPermissions

Method that checks whether the current user has a specific set of permissions. Throws an exception if the call fails.

ContentTypes

Collection property containing all the content types in the list.

Delete

Method that deletes the current list.

DoesUserHavePermissions

Method that checks whether the current user has a specific permission. Returns a Boolean value.

EventReceivers

Collection property containing all the event receivers of the website. Those are the event receivers installed on the SharePoint server, not the remote event receivers that are discussed in Chapter 10.

Fields

Collection property containing all the fields and/or site columns in the current list.

Folders

Collection property containing all the folders, if any, in the current list.

GetItemById

Method to get an item by using its unique numeric ID.

GetItems

Method with multiple overloads, used to get a subset of items. You will see more about this in the “Lists and items” section later in the chapter.

Hidden

Property that hides or shows the current list.

ID

Read-only property that represents the ID of the current list.

ItemCount

Read-only Int32 property that returns the number of items contained in the current list, including folders.

Items

Collection property containing the items in the current list.

RootFolder

Read-only property that returns the root folder of the list.

SchemaXml

Read-only String property that describes the list schema in XML of the currently selected list using CAML code (see the note following this table).

Title

Property to get or set the list title.

Update

Method that saves any pending list changes to the database.

Note

Collaborative Application Markup Language (CAML) is an XML-based querying language that is useful for defining filtering, sorting, and grouping on SharePoint data. The CAML querying language is the lowest-level way of accessing SharePoint data while looking for lists and items. The CAML language reference is available on MSDN, at http://msdn.microsoft.com/en-us/library/ms462365(v=office.15).aspx.

Just as with the SPWeb type, the SPList class provides an Update method that saves any changes applied in memory. Using the Server Object Model, you can browse the contents of existing lists, or you can create new lists from scratch and populate them with fresh new items. Whether you create new items or browse for existing ones, you must manage them as SPListItem instances. Table 5-4 shows some of the main members of the SPListItem type.

Table 5-4. Some of the members of the SPListItem type

Member name

Description

Attachments

Collection property containing the attachments, if any, of the current item.

BreakRoleInheritance

Method that breaks inheritance of role assignments for the current item and eventually copies role assignments from the parent list.

CheckPermissions

Method that checks whether the current user has a specific set of permissions. Throws an exception if the call fails.

ContentType

Read-only property that returns a reference to the content type associated with the current item.

ContentTypeId

Read-only property that returns the ID of the content type associated with the current item.

Copy

Static method to copy an item from one location to another within the same server. The method has a couple of overloads.

CopyFrom

Method that overwrites the current item with a source item provided as a URL from the same server.

CopyTo

Method that overwrites the target item, which is provided as a URL on the same server, with the current item.

Delete

Method that deletes the current item.

DoesUserHavePermissions

Checks whether the current user has a specific permission. Returns a Boolean value.

File

Read-only property that returns a reference to the file that corresponds to the current item when the item resides in a document library.

Folder

Read-only property that returns a reference to the folder associated with the current item when the item is a folder item.

ID

Read-only property that represents the ID of the current item.

Recycle

Method that deletes the current item, putting it into the Recycle Bin.

SystemUpdate

Method that saves any changes applied to the current item without affecting the Modified and Modified By fields of the current item, and optionally the item version.

Title

Property to get the item title.

Update

Method that saves any pending changes applied to the current item.

UpdateOverwriteVersion

Method that saves any changes applied to the current item without creating a new version of the item.

Url

Read-only property that returns the site-relative URL of the current item.

Versions

Collection property containing the version history for the current item.

Workflows

Collection property containing the workflows running on the current item. This property relates to the legacy workflow engine provided for backward compatibility with SharePoint 2010. For further details about workflows, see Part V of this book.

Xml

Read-only property that returns the current item as an XML fragment, using an XMLDATA (<z:row />) format.

Later in this chapter, the “Lists and Items” section shows how you can take advantage of some of these members in realistic scenarios.

SPDocumentLibrary and SPFile

Whenever you use an SPList instance, which corresponds to a document library, you can cast that instance to an SPDocumentLibrary type. This type represents a document library, which is almost the same as the base SPList type, but has a small set of more specific members related to file handling. As an example, an SPDocumentLibrary object provides a collection property through which you can enumerate all the currently checked-out files. When you need to enumerate the files contained in a document library, you can browse the SPListItem elements of the list and access their File property, which is of type SPFile. Browsing the files contained in an SPDocumentLibrary instance of an SPWeb object shows some sample code that browses the files of a document library and displays their name and size in bytes.

The SPFile class offers a rich set of members, as shown in Table 5-5.

Table 5-5. Some of the members of the SPFile type

Member name

Description

Approve

Method that approves a file submitted for content approval.

CheckedOutByUser

Read-only property that returns a reference to the SPUser instance for the user who checked out the file.

CheckIn

Method to check in the current file.

CheckOut

Method to check out the current file.

CheckOutType

Read-only property that returns the checkout status type for the current file. The possible values are defined in the SPCheckOutType enumeration: Online, Offline, and None.

CopyTo

Method that copies the current file to a specified destination URL within the same site, overwriting the target, if it exists. It has two overloads.

Delete

Method that deletes the current file.

Deny

Method to deny approval for a file submitted for content approval.

Length

Read-only property that returns the size in bytes (long) of the current file. When the file is a page, the property excludes the size of any Web Parts used in the page.

Lock

Method that applies a lock on the current file, preventing other users from modifying it.

LockedByUser

Read-only property that returns a reference to the SPUser object for the user who locked the file.

MoveTo

Method that moves the current file to a specified destination URL within the same site, overwriting the target, if it exists. It has four overloads.

Name

Read-only property that returns the file name.

OpenBinary

Method to read the file’s content into a Byte array. It has two overloads.

OpenBinaryStream

Method to read the file’s content as a Stream. It has three overloads.

Publish

Method to submit the file for content approval.

Recycle

Method that deletes the current file, putting it into the Recycle Bin.

SaveBinary

Method to save the contents of the current file, using a Stream or a Byte array. It has seven overloads.

Title

Property to get or set the file title.

UndoCheckOut

Method to undo the current checkout process for a file.

Update

Method that saves any changes applied to the current file.

Url

Read-only property that returns the site-relative URL of the current item.

Versions

Collection property containing the version history for the current item.

In the “Document libraries and files” section later in the chapter, you will see how to use some of these members to manage files stored in SharePoint.

SPGroup, SPUser, and other security types

Another set of useful types for developing real solutions are the SPGroup and SPUser classes. These correspond to a group and a SharePoint user, respectively, and both inherit from SPPrincipal. The SPPrincipal type ultimately inherits from SPMember. From a security point of view, a set of permissions is assigned to an SPPrincipal object using an SPRoleAssignment class. Thus, you can configure permissions equivalently for a user or for a group, using the same classes and syntax. An SPRoleAssignment object maps an SPPrincipal instance to an SPRoleDefinition instance. SPRoleDefinition is the type that defines a SharePoint permission level. In Part VI you will explore how SharePoint security works internally; for now, all you need is a high-level overview of these types. For example, Browsing role assignments and definitions for an SPWeb instance shows how to enumerate role assignments and role definitions.

When you target an SPUser object with a custom SPRoleAssignment instance, you will probably find the list of the main members of the SPUser type useful. You can see the most important members in Table 5-6.

Table 5-6. Some of the members of the SPUser type

Member name

Description

Alerts

Collection property containing any alerts configured by the user.

Email

Property that gets or sets the user’s email address.

Groups

Collection property containing the groups to which the user belongs.

ID

Read-only property that returns the user member ID (inherited from SPMember, through SPPrincipal).

IsSiteAdmin

Read-only property that returns true if the current user is a site collection administrator.

LoginName

Read-only property that returns the login name of the user.

Name

Property to get or set the display name of the user.

RawSid

Read-only property to get the raw binary Security ID (SID) of the user, in case the user is a Windows user.

Sid

Read-only property to get the SID of the user, in case the user is a Windows user.

Update

Method to save any changes applied to the current user.

UserToken

Read-only property to get a reference to the SPUserToken object of the current authentication process. It can be used to create an SPSite instance in order to impersonate the user, as already discussed at the beginning of this chapter.

Xml

Read-only property to get the current user as an XML fragment.

If you are targeting an SPGroup instance, it will help to know about some of the main members explained in Table 5-7.

Table 5-7. Some of the members of the SPGroup type

Member name

Description

AddUser

Method to add an SPUser to the current SPGroup.

Description

Property to get or set the description of the group.

ID

Read-only property to get the group member ID (inherited from SPMember through SPPrincipal).

Name

Property to get or set the display name of the group.

RemoveUser

Method to remove an SPUser from the current SPGroup.

Update

Method to save any changes applied to the current group.

Users

Property that allows enumerating the users belonging to the current group.

Xml

Read-only property to get the current group as an XML fragment.

These classes can be used to make authorization checks by code, or for managing automation of users and groups. For example, you can add a user to a group inside a custom timer job written using these classes. In the “Groups and users” section later in the chapter, you will see how to write this code.

SPControl and SPContext

One last group of types provided by the Server Object Model of SharePoint consists of some infrastructural classes such as SPControl and SPContext. The SPControl type is defined in the Microsoft.SharePoint.WebControls namespace. It is the base class for many SharePoint server controls, and it helps when developing web controls or Web Parts. Aside from its base class role, SPControl provides a small set of static methods, the most useful of which let you retrieve a reference to the current SPSite, SPWeb, or SPWebApplication instances. Here are the signatures of these methods:

public static SPModule GetContextModule(HttpContext context);
public static SPSite GetContextSite(HttpContext context);
public static SPWeb GetContextWeb(HttpContext context);
public static SPWebApplication GetContextWebApplication(HttpContext context);

All of these methods require an HttpContext object instance as their sole input argument.

Another way of obtaining a reference to the current SPSite and SPWeb is to use the SPContext class, which provides a static property named Current that references the current SharePoint context. The current SPContext object gives you direct access to all the most useful information about the current request. Table 5-8 shows the main members offered.

Table 5-8. Some of the members of the SPContext type

Member name

Description

ContextPageInfo

Read-only property that contains information about the current list item (permissions, list ID, list item ID, and so on) for the current request.

File

Read-only property that returns a reference to the SPFile instance, if any, corresponding to the SPListItem object served by the current request.

IsDesignTime

Read-only Boolean property to check whether the current request is running at design time.

IsPopUI

Read-only Boolean property to check whether the current request is for a pop-up dialog box.

Item

Read-only property that returns a reference to either the SPListItem object determined by the specified list and item ID or the SPItem object set when the context is created.

ItemId

Read-only property to get the ID (Int32) of the list item associated with the current context.

List

Read-only property that returns a reference to the SPList object associated with the current context.

ListId

Read-only property that returns the ID (GUID) of the list associated with the current context.

ListItem

Read-only property that returns a reference to the SPListItem object associated with the current context.

RegionalSettings

Read-only property that returns the regional settings of the current request context.

ResetItem

Method that forces a refresh of the current item. Internally, the method reloads the in-memory cached item from the content database.

Site

Read-only property that returns a reference to the SPSite object corresponding to the site collection of the current request context.

Web

Read-only property that returns a reference to the SPWeb object corresponding to the website of the current request context.

For a complete list of all the available types and members in the Server Object Model, see the full online reference on MSDN, at http://msdn.microsoft.com/en-us/library/ms464984.aspx.

Common and best practices

You will use the types discussed in the previous section, together with many others, throughout this book and in your real-world SharePoint solutions. Understanding what they do is important, but knowing how to use them correctly is even more so. The goal of this section is to share some thoughts and provide some best practices so that you can profitably use the Server Object Model.

Resource disposal

The first and most important hint you need to know is how to correctly release resources while working with objects of the Server Object Model. You can either wait for the .NET Framework to do it for you or release resources manually. Which option you choose is largely determined by how critical those resources are. By default, the .NET Framework employs a nondeterministic release of allocated managed objects, which is based on the garbage collector and provided by the common language runtime (CLR). When an instance of a managed type that you created is no longer used, the garbage collector automatically releases the allocated memory—but at a nondeterministic (unpredictable) time. When the managed object holds references to unmanaged resources—such as window handles, files, streams, database connections, sockets, and so forth—these unmanaged resources will be released only when the garbage collector collects memory. When such unmanaged resources are scarce, are critical, happen to lock physical resources, or use a large amount of unmanaged memory, you’re better off releasing them as soon as possible rather than waiting for the .NET garbage collector. To accomplish this goal, the .NET Framework infrastructure provides the IDisposable interface, which exposes a Dispose method that you should call to explicitly release these unmanaged resources. Here’s the definition of the IDisposable interface:

public interface IDisposable {
    void Dispose();
}

There are many patterns for implementing IDisposable; however, it is beyond the scope of this book to give you full coverage of this topic. To learn more about resource disposal in SharePoint, consult the article “Disposing Objects” on MSDN, at http://msdn.microsoft.com/en-us/library/ee557362.aspx.

More Info

To dig deeper into the CLR and garbage collector internals, consult Jeffrey Richter’s book, CLR via C#, Fourth Edition (Microsoft Press, 2012), available at http://www.oreilly.com/catalog/9780735667457/.

For now, suffice it to know that whenever a .NET type implements the IDisposable interface, you should invoke the Dispose method as soon as you no longer need the object. Calling Dispose lets you release unmanaged resources in a deterministic manner.

To invoke Dispose, you should adopt a standard technique, such as one of the following:

  • Use the using keyword.

  • Use a try…finally code block.

  • Explicitly invoke the Dispose method.

Employing the using keyword while working with an SPSite instance to ensure timely disposal of unmanaged resources shows a code excerpt that takes advantage of the using keyword.

The compiler converts the using keyword into a try…finally code block, such as the one in Using the try…finally block while working with an SPSite instance to ensure timely disposal of unmanaged resources.

If you need to catch exceptions that might occur while working with disposable objects, wrap the using block or the try…finally block with an external try…catch block, as shown in Wrapping the using block in an external try…catch block while working with an SPSite instance so it can handle any exceptions.

Writing code this way ensures that any unmanaged resources will be released as soon as they are no longer needed. It also ensures that exceptions can be handled without overloading the environment.

You should apply this technique even when using objects from the SharePoint Server Object Model. For example, the SPSite and SPWeb types both implement the IDisposable interface, and both allocate unmanaged memory. If you do not correctly release SPSite and SPWeb instances, you will probably experience memory leaks, crashes, and frequent application pool recycles because of extra (and unnecessary) memory consumption.

However, you must also be careful, because you should dispose of these types only when you have explicitly created them. For example, Incorrect object disposal through the using keyword illustrates a situation in which you should not dispose of an SPSite instance.

In Incorrect object disposal through the using keyword, the SPSite instance is retrieved from the request context through the SPControl type. Thus, you didn’t create it; the internal SharePoint Foundation code did. This means you are not responsible for disposing of it. The same logic applies to SPSite or SPWeb references retrieved from the current SPContext object. In contrast, The correct way to handle objects that do not need to be disposed of explicitly shows you the correct way to write the code.

For situations in which you create both SPSite and SPWeb instances within the same code excerpt, you should employ nested using keywords, as you can see in many examples in this chapter (such as Browsing role assignments and definitions for an SPWeb instance).

Keep in mind that if you are browsing a collection of SPWeb items—for example, enumerating the AllWebs property of an SPSite object—you are responsible for releasing each single SPWeb instance, as exemplified in Object disposal while iterating collections.

Furthermore, there are types that internally create instances of SPSite or SPWeb that you’ll need to dispose of explicitly. For example, the SPWebPartManager and the SPLimitedWebPartManager classes internally use an SPWeb instance that must be disposed of. These types all implement IDisposable, so you should handle them almost the same way as you do the SPSite and SPWeb types.

Handling exceptions

A perennially interesting area when developing software solutions is that of exception handling for intercepting code failures. The SharePoint Server Object Model provides a base class named SPException, which is the default exception thrown by the SharePoint Server Object Model and is also the type from which almost every specific SharePoint exception inherits. While handling exceptions, consider a few suggestions.

First, catch and handle only those exceptions that you anticipate and can manage. In other words, you should avoid simply catching all exceptions using a catch all block or an empty catch block. That way, when an exception that you don’t anticipate occurs, it will bubble up to higher-level code that is able to handle it, if any exists. If the exception is unexpected through the entire stack of the current request, it’s best to let the software crash. (Of course, you would inform the end user in a friendly manner and possibly automatically alert technical support.) That is exactly what SharePoint does by default for unhandled exceptions. Figure 5-2 shows the default error message that SharePoint displays when an unexpected error occurs.

A screen shot of the default error message provided by SharePoint 2013. A brief and user-friendly error message is followed by technical details and a correlation ID that will enable IT professionals and developers to investigate the issue.

Figure 5-2. The default message that SharePoint 2013 displays when an unexpected error occurs.

More Info

The default location for the Microsoft SharePoint 2010 Unified Logging System (ULS) logs is in the SharePoint15_RootLOGS folder. You can search the log manually using any basic text editor. Alternatively, the log is compatible with the free ULS viewer, which you can download from http://archive.msdn.microsoft.com/ULSViewer.

The correlation ID (GUID) shown in the message refers to the current request context, which you can use to search for the exception in the SharePoint ULS log. Specifically, search for a row of type Unexpected that contains the correlation ID from the error dialog at the end of the row. That’s where you can find the unhandled exception details and stack trace.

If you decide to catch unexpected exceptions with code of your own (and thereby avoid the default error message), you will probably still want to log/trace the exception by yourself. Logging an exception to the ULS log shows how to manage an unexpected exception by logging it to the ULS log.

Logging an exception to the ULS log illustrates that the SPDiagnosticService provides utilities for logging into the ULS log of the local server, through the WriteTrace method.

Transactions

Working within a transactional environment when manipulating data is a common application need; however, the SharePoint data engine and the SharePoint Server Object Model are not transactional. You cannot rely on them alone to build a transactional system. In fact, SharePoint is not an RDBMS. Data you store in SharePoint lists should not be critical and should not require a transactional environment. If you do need to store information in SharePoint using a kind of transactional behavior, you need something like a compensable system. For example, you can use a Windows Workflow Foundation 4.5 workflow that makes use of a CompensableActivity activity. Let’s see what that means in concrete terms.

More Info

For further details about Windows Workflow Foundation, read Part V of this book.

Whenever you invoke the Update method for a Server Object Model object (such as SPListItem), SharePoint updates the corresponding data in the target content database. If you change two or more items and you want to update either all or none of them, you must keep track of such changes yourself (in case you need to revert back to the original values if the process fails) because SharePoint doesn’t support this. The same is true when you need to update data on SharePoint or update data using an external resource manager, such as an RDBMS. If you update the SharePoint content database first and then the RDBMS update fails, you will need to manually restore the original content values on the SharePoint side, using some custom code.

If you must have transactional support while managing data stored in SharePoint, you should probably ask yourself whether SharePoint is truly the appropriate place to store that data. Of course, the answer would be no. In such critical cases, you need a transactional RDBMS instead. You can still use SharePoint to present such data to end users, however, by taking advantage of Business Connectivity Services and external lists for this purpose.

AllowUnsafeUpdates and FormDigest

To avoid cross-site scripting issues, SharePoint applies a security check whenever you change data through the Server Object Model during HTTP requests. In fact, by default, SharePoint web forms use a form digest control to enforce security. The FormDigest is a hidden field that is sent by SharePoint web forms via HTTP POST, and checked by the security infrastructure on the server. When you make changes to objects by using the Server Object Model during an HTTP GET request, this input field will be missing, so by default SharePoint will throw an exception that looks like this excerpt:

Microsoft.SharePoint.SPException: The security validation for this page is invalid.

Similarly, if you send an HTTP POST request with a missing or invalid FormDigest value, you will receive the same error. This behavior applies only during HTTP requests. Therefore, when you reference the Server Object Model in a class library or a batch tool that runs outside of the ASP.NET pipeline, the security check will not occur. In fact, the check process looks for the HttpContext.Current variable; if it is null, the digest validation will not occur.

With that in mind, if you are developing a webpage that will respond to HTTP GET requests, or a custom web form page that doesn’t inherit from the WebPartPage type and doesn’t use the FormDigest control, you will need to instruct SharePoint to skip the digest validation; otherwise, your code will not work.

To instruct SharePoint to skip the validation, set the Boolean AllowUnsafeUpdates property of the current SPSite or SPWeb object to true. Using the AllowUnsafeUpdates property of the SPWeb type to skip a security check shows an example.

The code in Using the AllowUnsafeUpdates property of the SPWeb type to skip a security check works with an SPWeb instance provided by the current SPContext instance. It sets the AllowUnsafeUpdates property to true before changing an SPList instance property, and then resets the property to false (its default value) just after invoking the SPList.Update method. To ensure that the AllowUnsafeUpdates property always reverts to its original value, the code uses a try…finally code block.

Conversely, when you develop a custom ASPX page and you want to exploit the security environment provided by SharePoint, you have a couple of choices. You can inherit from WebPartPage, or you can manually include a FormDigest control in your page. In the first case, you simply need to inherit from the Microsoft.SharePoint.WebPartPages.WebPartPage base class, which internally renders a FormDigest control. Then, in your code, you call the utility method SPUtility.ValidateFormDigest() to check the digest when you post the page back to the server. In the latter case, you need to include the Microsoft.SharePoint.WebControls.FormDigest control in your page(s), and you still need to invoke the SPUtility.ValidateFormDigest() method to check the digest.

Of course, in a custom ASPX page, you could also invalidate the security check by setting the AllowUnsafeUpdates property to true. However, that would be both insecure behavior and poor practice.

Real-life examples

The purpose of this section is to give you some concrete examples from real-life solutions that illustrate how to work with SharePoint Server Object Model types. The examples are divided into groups based on the target object and target goal. You should consider this section as an everyday reference for developing SharePoint solutions. Look to the following code excerpts for inspiration while developing custom controls, Web Parts, custom pages, timer jobs, or whatever else will have to run on a SharePoint server.

Creating a new site collection

This first example shows how to create a new site collection in code (see Creating a new site collection).

Creating a new site collection uses the method of the SPSiteCollection type, to which you can get a reference from the SPWebApplication.Sites property. The method has many different overloads; the code excerpt uses one of the most complete signatures, which is as follows:

public SPSite Add(
    string siteUrl,
    string title,
    string description,
    uint nLCID,
    uint compatibilityLevel,
    string webTemplate,
    string ownerLogin,
    string ownerName,
    string ownerEmail,
    string secondaryContactLogin,
    string secondaryContactName,
    string secondaryContactEmail,
    string databaseServer,
    string databaseName,
    string userName,
    string password
)

This example shows that you can define each and every detail of the site collection configuration, including the website template name to use, and you can even assign a dedicated content database. Table 5-9 lists some of the most common website template values.

Table 5-9. Some of the most common website template names available in SharePoint for creating a new site collection

Site template name

Description

STS#0

Team site (15 or 14)

STS#1

Blank site (15 or 14)

STS#2

Document workspace (15 or 14)

MPS#0

Basic meeting workspace (15 or 14)

MPS#1

Blank meeting workspace (15 or 14)

MPS#2

Decision meeting workspace (15 or 14)

MPS#3

Social meeting workspace (15 or 14)

MPS#4

Multipage meeting workspace (15 or 14)

CMSPUBLISHING#0

Publishing site (15 or 14)

SPSPORTAL#0

Collaboration portal (15 or 14)

COMMUNITY#0

Community site (15 only)

COMMUNITYPORTAL#0

Community portal (15 only)

More Info

To list all the available site templates names, descriptions, and compatibility levels for a specific farm, use PowerShell and the Get-SPWebTemplate cmdlet command.

Creating a new site collection assumes that the site collection (http://devbook.sp2013.local/) will allow you to create another site collection under the sites managed path of the parent web application. The sites managed path is available out of the box for any SharePoint web application. If you need to create a root site collection from scratch, however, you should retrieve a reference to the SPWebApplication instance through an SPFarm object.

Creating a new website

After you have a site collection, at some point you will probably need to create one or more websites in it. Creating a new website contains a code excerpt that uses the SPWebCollection.Add method. The method also has many overloads. The following is the overload signature used in Creating a new website:

public SPWeb Add(
    string strWebUrl,
    string strTitle,
    string strDescription,
    uint nLCID,
    string strWebTemplate,
    bool useUniquePermissions,
    bool bConvertIfThere
)

While creating a website, you can specify a website template name or an object of type SPWebTemplate. This last type has a CompatibilityLevel property, which enables you to specify whether you are creating a SharePoint 2010 or SharePoint 2013 site. Some of the available values for this argument are illustrated in Table 5-10.

Table 5-10. Some of the website template names available in SharePoint for creating a new website

Site template name

Description

STS#0

Team site

STS#1

Blank site

WIKI#0

Wiki

BLOG#0

Blog

CMSPUBLISHING#0

Publishing site

BLANKINTERNET#0

Blank publishing site

Note the Boolean useUniquePermissions argument that’s used in Creating a new website. This is useful for specifying whether to inherit permissions from the parent site collection or whether the new site should have unique permissions. The bConvertIfThere argument is also interesting; when true, it instructs SharePoint to convert an existing folder into the child website; when false, it causes SharePoint to throw an exception if a folder already exists with the URL requested for the new website.

Of course, to be able to create a new website inside an existing site collection at all, you need to access the Server Object Model with a user account that has sufficient permissions.

Lists and items

This section includes several examples related to managing lists and list items. For example, you will learn how to create lists, as well as how to create, update, and delete items within those lists.

Creating a new title

To create a new list of items, you can use Creating a new list of contacts in a website and configuring the list properties as a pattern. It demonstrates how to create a list of contacts and configure the list properties.

Creating a new list of contacts in a website and configuring the list properties exploits the SPListCollection.Add method, using one overload that specifies the list template using an enumeration value. Here’s the signature of the Add method used:

public virtual Guid Add(
    string title,
    string description,
    SPListTemplateType templateType
)

The SPListTemplateType enumeration defines about 60 templates that cover the most common list scenarios. If you wish to create a list using a custom template, you can browse the ListTemplates property of the current SPWeb instance, selecting the corresponding SPListTemplate instance and using the following overload of the SPListCollection.Add method instead:

public virtual Guid Add(
    string title,
    string description,
    SPListTemplate template
)

All the overloads of the SPListCollection.Add method return a Guid value that corresponds to the ID of the newly created list. To configure the list you just created, you need to retrieve a reference to it using that ID. Creating a new list of contacts in a website and configuring the list properties uses the SPList object to configure the list so that it will appear on the Quick Launch menu. It configures the default item-level permissions to let all users read every item but change only items that they created. You can see the result of this item-level permissions configuration made through code in Figure 5-3.

Remember, as soon as you have finished configuring any object from the Server Object Model, you must invoke the Update method to confirm the changes.

A screen shot of the Advanced Settings page of a list showing the permissions set by . No management of content types is allowed; however, read access to all items, creating items, editing items created by the user, and adding attachments to list items are all allowed.

Figure 5-3. Item-level permissions resulting from the code in Creating a new list of contacts in a website and configuring the list properties.

Creating a new list item

After creating a list, you will want to populate it with new items. The code in Populating a list with new items adds a new contact item to the list created in Creating a new list of contacts in a website and configuring the list properties.

Again, you need to invoke an Add method for the corresponding collection—in this case, an SPListItemCollection. The method returns a new SPListItem instance ready to be configured and updated against the content database. To be accurate, the Add method simply creates a new item configured according to the target list in terms of fields, content types, and so on. However, despite its name, the Add method does not really add the item to the list; in fact, the new SPListItem instance has an ID with a value of zero (0). Only after you invoke the Update method of the item for the first time will it be inserted into the list and have a unique ID assigned. The code in Populating a list with new items configures three fields of the target item. The syntax you use to assign values to the fields uses each field’s DisplayName; however, the indexer of an SPListItem lets you provide as arguments the DisplayName, the Name, the StaticName of the field, the unique ID of the field (which is useful when you are working with provisioned site columns), or the ordinal position (index) of the field within the Fields collection of the current item.

More Info

To better understand topics such as site columns, DisplayName, Name, StaticName, and so on, see Chapter 2 and Chapter 3

For completeness, the example code catches exceptions of type ArgumentException, just in case you provide an invalid list title or field name. In general, you should avoid writing list titles or field names in source code; instead, you should work with provisioned contents and their corresponding IDs. Using the IDs essentially eliminates the possibility of an invalid value at run time (unless you make a typing mistake while writing the code)—but those types of issues should become apparent during testing, before the application ever reaches a production environment.

Modifying an existing list item

Another common task is modifying the metadata of an existing item. The procedure is similar to creating a new list item; the only difference is that you need to query the list to get a reference to the item that you want to update. The example in Modifying an existing item of a list retrieves the item to update using its unique ID, via the SPList.GetItemById method.

Note that the SPList.GetItemById method retrieves the full item, with all its columns of metadata. When you need to change just a few columns, it’s best to retrieve only those specific columns. To do that, use the SPList.GetItemByIdSelectedFields method, which retrieves only the columns you specify. In this case, the line from which the example retrieves the item to change could be

SPListItem itemToChange = list.GetItemByIdSelectedFields(1, "Last Name");

But the SPList.GetItemByIdSelectedFields method also accepts a list of fields to retrieve from the content database as a params array of String.

When you don’t know the ID of the item that you want to update, you can use the SharePoint query engine—a topic covered later in this chapter, in the “Querying for list items” section.

Concurrency conflicts

Any server-side code has the potential to serve an unpredictable number of users, so changing data in a back-end RDBMS carries the possibility of a concurrency conflict. Concurrency issues can also happen when working with data stored in SharePoint. Thus, due to the nature of SharePoint, which is a web-based product with (hopefully) a large number of concurrent users, it is highly probable that concurrency conflicts will arise while managing SharePoint items. Fortunately, the SharePoint team provided a standard pattern for catching concurrency conflicts. Consider the example in Catching concurrency in SPListItem management, which changes an SPListItem object with two different concurrent sessions.

When the code in Catching concurrency in SPListItem management invokes the Update method to save changes, a concurrency conflict exception will be raised because the ChangeListItemConcurrently procedure has already changed that item. The exception will be a Microsoft.SharePoint.SPException with this error message:

Save Conflict. Your changes conflict with those made concurrently by another user. If you want your changes to be applied, click Back in your Web browser, refresh the page, and resubmit your changes.

The error message is tightly tied to a web scenario (notice “click Back in your Web browser”). However, the exception itself can be caught within any kind of software solution—even running on a SharePoint server. To solve this exception, you must reload the SPListItem object from the content database and then apply your changes again, just as a web user would do using his or her web browser.

Deleting an existing list item

Deleting an SPListItem instance is a common task, similar to inserting or updating items. The program flow for deleting an item is both simple and quick, as you can see in Deleting an SPListItem instance.

You simply need to retrieve the SPListItem instance that corresponds to the item that you want to delete, and then invoke the Delete method (to permanently delete the item) or the Recycle method (to move the item into the Recycle Bin).

Querying for list items

As previously discussed, retrieving an SPListItem instance by ID is an uncommon task, unless you have a custom ASPX page that receives the ListID and the ListItemID values as QueryString parameters. More generally, you need to retrieve items from lists using a query that is based on the metadata of the items you want to extract. For example, you might need to extract all contacts whose email address contains @devleap.com. The Server Object Model provides a class named SPQuery, through which you can execute a CAML query against an SPList instance to retrieve items corresponding to the query. Querying the items of an SPList instance using an SPQuery object shows an example.

Note

If you don’t like writing CAML queries, try CAML Designer for SharePoint 2010, by Karine Bosch, which targets SharePoint 2010 and 2013. You can download this free tool from http://karinebosch.wordpress.com/my-articles/caml-designer/.

Querying the items of an SPList instance using an SPQuery object configures some of the properties of the SPQuery type, the most important of which is the Query argument, which contains the CAML code. However, the SPQuery type also has other properties that are even more fundamental for performance, such as the ViewFields property, which returns only specifically referenced columns, and thus avoids forcing the server to retrieve useless columns. The previous example marks the ViewFieldsOnly property as true. The SPQuery type also has a RowLimit property that supports partitioning of data results, such as for paging results. Querying the items of an SPList instance using an SPQuery object with paging shows how to take advantage of the RowLimit property together with the SPQuery.ListItemCollectionPosition property to page results in blocks of five items for each page.

When you execute the code in Querying the items of an SPList instance using an SPQuery object with paging against a list of contacts with a fictitious set of items, you will see the following console output:

Current Page: 1
1 - First Name 001 Last Name 001 - [email protected]
2 - First Name 002 Last Name 002 - [email protected]
3 - First Name 003 Last Name 003 - [email protected]
4 - First Name 004 Last Name 004 - [email protected]
5 - First Name 005 Last Name 005 - [email protected]
Current Page: 2
6 - First Name 006 Last Name 006 - [email protected]
7 - First Name 007 Last Name 007 - [email protected]
[etc. ]

The ListItemCollectionPosition property is of type SPListItemCollectionPosition. It offers a PagingInfo property of type String, which contains the following data:

Paged=TRUE&p_ID=8

The _ID is the unique identifier of the last item retrieved; this allows SharePoint to know the starting position of the next page.

The SPQuery type offers many other properties; however, those I’ve described here will generally suffice for everyday tasks.

Document libraries and files

Document libraries and files are critical for many real-world SharePoint solutions. In this section, you will learn how to create document libraries, and how to upload, download, update, and manage documents. Remember that in SharePoint 2013, a document library, from a web UI perspective, is shown as an app. However, it is still a document library as it was in previous editions of SharePoint.

Creating a new document library

To create a new document library, you just need to write code using an SPListTemplateType value of DocumentLibrary, such as was shown in Creating a new list of contacts in a website and configuring the list properties. Although this creates a library, the library is an empty one. Because many corporations require documents to be formatted in a standardized way, quite often you may need to provide a document template to use for new documents. The code in Creating a new SPDocumentLibrary instance with a document template creates a library of invoices with an Excel spreadsheet document template.

When run, the code in Creating a new SPDocumentLibrary instance with a document template creates a new document library that you can reference as an instance of the SPDocumentLibrary type. Notice the LINQ to Objects query that is used to determine the SPDocTemplate item that corresponds to an Excel spreadsheet. Table 5-11 lists all the document templates available in a team site (STS#0) along with their DocTemplateID identifiers.

Table 5-11. The document templates available in SharePoint

DocTemplate ID

Description

100

No template used by the document library

101

A blank Microsoft Word 97–2003 document

103

A blank Microsoft Excel 97–2003 document

104

A blank Microsoft PowerPoint 97–2003 document

121

A blank Microsoft Word document

122

A blank Microsoft Excel document

123

A blank Microsoft PowerPoint document

111

A basic Microsoft OneNote 2010 Notebook

102

A blank Microsoft SharePoint Designer HTML document

105

A blank Microsoft basic page ASPX document

106

A blank Microsoft Web Part page ASPX document

1000

An empty Microsoft InfoPath form, ready for design

You can find all these IDs of the document templates for a team site in the ONET.xml files, in the folder SharePoint15_RootTEMPLATESiteTemplatesstsxml. You can also find them in the SharePoint software development kit (SDK), which is available online and as a free download.

Uploading a new document

After you create a library, uploading new content to it is simple. Recall that Table 5-3 showed that each SPList instance has a RootFolder property and a Folders collection property. You can reference any SPFolder object to browse for its contents or to upload new content using the Add method of the Files property, which is of type SPFileCollection. The code excerpt in Uploading a new document to an SPDocumentLibrary instance uploads a dummy Excel invoice file to the root folder of the library that was created in Creating a new SPDocumentLibrary instance with a document template.

The Add method has 20 overloads. The preceding code used the one that accepts the destination URL of the file, an argument of type System.IO.Stream for the content of the file to upload, and a Boolean value that, when true, instructs SharePoint to overwrite any previously existing file. Detailed examples of all the overloads is beyond the scope of this book; however, it is interesting to group them on a functional basis. All the overloads accept the destination URL of the file as their first argument. But one group of overloads accepts the file as an object of type System.IO.Stream, and another group takes a System.Byte[] array as input. Additionally, there is a group that accepts an argument of type HashTable, which is a property bag for a file’s metadata. This family of methods is useful whenever you need to upload a file along with its metadata in a unique transaction. Lastly, there are a couple of overloads that accept an argument of type SPFileCollectionAddParameters, which lets you specify some options about how to handle check-ins and check-in comments, and so on.

More Info

You can find a complete overload reference online, at http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spfilecollection.add.aspx.

Downloading a document

For document libraries, downloading is, of course, a frequent task. Every SPListItem object in a document library has a File property of type SPFile. Through that property, you can access the file’s content as either an object of type System.IO.Stream or as an array of bytes (System.Byte[]). Downloading a document from an SPDocumentLibrary instance presents an example that downloads the file that was uploaded in Uploading a new document to an SPDocumentLibrary instance.

The key points in Downloading a document from an SPDocumentLibrary instance are the SPWeb.GetFile method, which is a shortcut to retrieve an SPFile instance for a specified file URL, and the OpenBinaryStream method of the SPFile class. The remaining code is plumbing to manage streams and save bytes on the hard disk.

Document check-in and checkout

Another common task while managing documents is working with checkout and check-in features. As was shown in Table 5-5, the SPFile class provides some specific methods to handle these tasks. Checking a document out and back in shows a code excerpt that checks out a file and then checks it back in again, adding a comment.

When checking out a document, you should first evaluate the CheckOutType property, which is of type SPFile.SPCheckOutType—an enumeration of the following values:

  • None. The file is not checked out.

  • Offline. he file is checked out for editing on the client side.

  • Online. The file is checked out for editing on the server side.

When the CheckOutType value is None, you can invoke the CheckOut method, optionally specifying the type (Offline or Online) of checkout that you want to occur. Otherwise, you can check the file in using the CheckIn method, providing a comment and optionally an argument of type SPCheckinType, which can assume the following values:

  • MajorCheckIn. The check-in increments a major version of the file.

  • MinorCheckIn. The check-in increments a minor version of the file.

  • OverwriteCheckIn. The check-in overwrites the current file version.

One last option you have is the UndoCheckOut method, which releases a checkout without modifying the existing stored copy of the file.

Copying and moving files

Quite often in workflows and event receivers, you need to copy a file from one folder to another or move a file from one library to another.

More Info

For further details about SharePoint workflows, see Part V of this book.

These actions are fully supported by the SharePoint Server Object Model. The example in Copying and moving a document from one location to another copies or moves a file based on a provided argument.

Copying and moving a document from one location to another assumes that you have a library named Invoices and a library named Invoices History, and that you are copying or moving files between these two libraries. Whether you move or copy a file, both the methods receive a Boolean argument to force overwriting of any previously existing file in the target folder. Note that both of these methods work only within the same site.

Managing versions of documents

While working with files, you often need to manage versioning to keep track of changes during a file’s life cycle and to retrieve older versions of a document. How to manage file versions shows an example that extracts the next-to-last version of a document.

How to manage file versions demonstrates that SharePoint makes managing file versions simple. For each available version of the document, you have access to an SPFile instance that you can manage exactly as you would the current version of the document.

Groups and users

The tasks discussed in this section involve the management of users and groups. You will learn how to create and manage a user, how to control users’ membership against groups, and how to define custom permission levels to assign specific permissions to users or groups.

Creating a new user

As usual, the first step in the sequence of common tasks is to be able to create a new item. Remember that a user in SharePoint is an SPUser instance. Each SPWeb instance offers a set of user collections (AllUsers, SiteUsers, Users), which were listed in Table 5-2. Adding a new user to the Users collection of a group of a site shows how to add a new user, taken from Active Directory, into the list of users for a group of a site.

The SPUserCollection.Add method accepts the logon name of the user, the email address, the display name, and an optional argument with textual notes about the SPUser Instance. When you add a previously existing user, the infrastructure ignores any duplicate insertion. However, if you simply want to get a valid SPUser instance that corresponds to a logon name—and you don’t want to worry about whether that user exists—you can invoke the SPWeb.EnsureUser method. This method adds the user if that user is not already defined in the site, or uses the existing user, if there is one. Adding a new user to a site with the EnsureUser method shows a revised example.

This time, the EnsureUser method directly returns the SPUser that you’re probably expecting.

Managing group membership

Deleting a user and managing user properties are trivial tasks, so this chapter will not cover them. But it is interesting to know how to add a user to a specific SharePoint group. There are many techniques to accomplish this; however, in Adding a user to a website group you will see how to do that by working with the Groups collection of the current SPWeb instance, which is the most common technique.

The example is clear; the last line invokes the AddUser method of an SPGroup object retrieved by group name. Using the SPWeb.Groups collection, you can also add, update, or delete existing SharePoint groups; however, you should be very careful when performing such actions in code, because the security model should be managed by an IT professional—and having code that creates users and groups on its own could reduce the security of the overall environment if not well defined and documented.

Managing user and group permissions

In the “SPGroup, SPUser, and other security types” section earlier in the chapter, you learned that both users and groups internally inherit from SPPrincipal, which is a fundamental type for assigning permissions. In SharePoint 2013, permissions are based on permission levels. A permission level consists of a set of low-level permissions, such as Browse Directory, View Pages, View Items, Add Items, and so forth. For a full and detailed list of all the available permissions and native permission levels, see Chapter 19. For now, you just need to know that you can define custom permission levels using either the browser UI or the Server Object Model. Additionally, you can assign a permission level to an SPPrincipal object (an instance of type SPUser or SPGroup). Creating a new permission level and assigning it to a user shows a code excerpt that creates a new permission level (composed of the following permissions: View Pages, Browse Directories, and Update Personal Web Parts) and assigns it to a specific SPUser instance.

The code in Creating a new permission level and assigning it to a user first retrieves a reference to an SPUser object, and then it creates a new permission level—a new instance of SPRoleDefinition—and assigns a set of selected permissions to it using a bit mask of permissions. Finally, it adds a binding between the SPPrincipal object representing the user and the permission level, using a new SPRoleAssignment instance.

Summary

This chapter provided an overview of the SharePoint Server Object Model, starting with the main SharePoint object hierarchy. It then provided a description of the main types. Finally, it explored basic types of everyday tasks, their problems, and solutions. It also included some suggestions and best practices for writing better and more efficient code. With this as a foundation, you’re ready to take on the rest of Part II and Part III, which will expand your knowledge and use the Server Object Model to create business solutions.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset