Logo
HOW TO
Windows XP
Windows Vista
Windows 7
Windows Azure
Windows Server
Windows Phone
 
 
Windows Server

Developing with SharePoint 2010 (part 3) - Server Object Model

2/6/2013 4:40:51 PM

Many years ago, back when software shipped with printed manuals, I occasionally dabbled in a bit of development with Microsoft Access 2.0. Although the developers’ manual that Microsoft provided with Access covered the ins and outs of the product in great detail, the thing that I found most useful was the pseudo-class diagram that was printed on the back cover. In my opinion, there’s no easier way to find your way around a new object model. Bearing that in mind, the following illustration is my SharePoint 2010 hierarchy. Of course, the actual object model is far more complicated, but as a tool, this will help you get up to speed quickly.


We’ll work through the objects on the diagram to build an understanding of what each one represents and how you might use it in development. We’ll use a console project to execute our code samples. Take the following steps:

  1. In Visual Studio 2010, choose File | New | Project.

  2. In the New Project dialog, select Console Application. Name the new project Chapter2, as shown. Ensure that the framework is set to .NET Framework 3.5. Click OK.

    Earlier I discussed the problems that can arise when debugging and unit testing SharePoint applications due to the 64-bit nature of the SharePoint platform. Console Application projects are created with a default build configuration of x86, meaning that they will be built as 32-bit assemblies. Since these will not work when targeting SharePoint, we need to change the default build configuration.

  3. In the Solution Configuration drop-down, select Configuration Manager, as shown next:

  4. From the Active Solution Platform drop-down, select <New..>, and then in the New Solution Platform dialog, select x64 as the new platform, as shown:

  5. Close the Configuration Manager dialog to return to the project.

  6. Add a reference to Microsoft.SharePoint by choosing Project | Add Reference, and then select Microsoft.SharePoint from the .NET tab.

Administration and Configuration Classes

The following classes are generally used for administration and configuration purposes. Many of these are commonly used when implementing service applications..

SPFarm

It will probably come as no surprise to learn that the SPFarm object represents the SharePoint farm. Server Object Model code must be executed on a server that is a member of a SharePoint farm (or on a single stand-alone server, which is effectively a farm with only one server in it), and because of this we can obtain a reference to the SPFarm object that represents the current farm by using code such as this:

class Program
  {
    static void Main(string[] args)
    {
      Program p = new Program();
      p.ListServersInFarm();
      Console.WriteLine("Press enter to exit...");
      Console.ReadLine();
    }
     void ListServersInFarm()
     {
       Console.WriteLine("Servers in farm:");
       foreach (SPServer server in SPFarm.Local.Servers)
       {
         Console.WriteLine(server.DisplayName);
       }
     }
  }

SPServer

The SPServer object represents a specific server within a SharePoint farm. Again, since all Server Object Model code must run on a server within a SharePoint farm, we can pick up a reference to the current SPServer object as follows:

void ListServicesOnServer()
{
  Console.WriteLine("Services on local server");
  foreach (SPServiceInstance service in SPServer.Local.ServiceInstances)
  {
    Console.WriteLine(service.TypeName);
  }
}

SPService

At its most fundamental, SharePoint is a platform for running services across a farm of servers. These services can include features such as Web Services, which use IIS to provide web-based content, or Search Services, which provides search functionality to other services within the farm.

SPServiceInstance

Since a SharePoint farm may have many servers, each platform server may have more than one instance. The SPServiceInstance object represents an instance of a service that is running on a particular server.

SPWebService

The SPWebService is the parent service that hosts all front-end web sites within a SharePoint farm.

Site Provisioning and Content Access Classes

The following classes are used for programmatically provisioning sites as well as for accessing data contained within sites, lists, and libraries. These classes will be commonly used in all SharePoint development.

SPWebApplication

>As you saw earlier when we walked through the creation of a SharePoint site, the web application is the topmost object in the site provisioning hierarchy. Each web application that’s configured on a SharePoint farm is represented by an SPWebApplication object in the Server Object Model:

void ListWebApplications()
    {
      Console.WriteLine("Web applications in farm:");
      SPWebService webService = SPFarm.Local.Services.
      OfType<SPWebService>().First();
      foreach (SPWebApplication app in webService.WebApplications)
      {
        Console.WriteLine(app.Name);
      }
    }

SPSite

This is where it gets confusing! The next level in the site provisioning hierarchy is the site collection. However, within the SharePoint Object Model, each site collection is represented by an SPSite object. The SPSite object is one of the primary entry points to the Server Object Model and will be used frequently in SharePoint application development.

The following code snippet shows how to create an SPSite object explicitly. Notice that the SPSite object is defined within a using block, this is recommended practice whenever an SPSite object is created.

void ListSitesInSiteCollection()
    {
      Console.WriteLine("Sites in site collection:");
      using (SPSite site = new SPSite("YourSiteCollectionURL"))
      {
        foreach (SPWeb web in site.AllWebs)
        {
          Console.WriteLine(web.Title);
          web.Dispose();
        }
      }
    }

SPWeb

Continuing with the theme of confusion, within the model, sites are represented by SPWeb objects. Although SPSite objects are the primary entry point to the model, picking up references to objects that we’ll likely be writing code against will require a reference to an SPWeb object. The following code snippet shows how to obtain a reference to the root site in a site collection:

void ListListsInRootWeb()
    {
      Console.WriteLine("Lists in site collection root site:");
      using (SPSite site = new SPSite("YourSiteCollectionURL "))
      {
        using (SPWeb root = site.RootWeb)
        {
          foreach (SPList list in root.Lists)
          {
            Console.WriteLine(list.Title);
          }
        }
      }
    }

As well as explicitly creating SPWeb objects, references to the current SPWeb object can often be obtained from other sources. For example, when you’re writing code that runs in the context of a web page, the static SPContext.Current property provides a reference to the current SPWeb object, as this code snippet shows:

SPList list = SPContext.Current.Web.Lists.TryGetList(ListName);
if (list == null)
{
   //do stuff
}

SPList

Most SharePoint content is stored within lists or document libraries. Within the Server Object Model, both lists and document libraries are represented by an SPList object. Although not included in our diagram, document libraries are also represented by SPDocumentLibrary objects. The SPDocumentLibrary class is derived from the SPList class and provides additional functionality that is appropriate for document libraries. Other classes are derived from SPList and represent specific types of list; for more information, see http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splist.aspx.

SPListItem

As mentioned, most content within a SharePoint site is accessed via an SPList object. Each item in a list or library is in turn represented by an SPListItem object that is accessed via the SPList.Items collection. The SPList class and the SPListItem class will feature heavily in practically all development on the SharePoint platform. 

SPFile

Although almost all content is represented by an SPListItem object, where the content in question is a file, the SPListItem object only represents the metadata for the file. For example, if we create a document library and upload a Word document, the SPListItem object that represents the document will contain only the document title as well as a few additional system-generated metadata fields. To perform work on the document, we need to use an SPFile object as shown next.

void ListRootWebMasterPages()
    {
      Console.WriteLine("Master Page files in site collection root site:");
      using (SPSite site = new SPSite("YourSiteCollectionURL"))
      {
        using (SPWeb root = site.RootWeb)
        {
          SPList masterPages = root.Lists.TryGetList("Master Page Gallery");
          if (masterPages != null)
          {
            SPListItemCollection items = masterPages.Items;
            foreach (SPListItem fileItem in items)
            {
              SPFile file = fileItem.File;
              Console.WriteLine(file.Name + "\t" +  string.Format("{0:###,### →
bytes}",file.Length));
            }
          }
        }
      }
    }


					  

SPFolder

Most user-generated content within SharePoint sites is stored in lists and document libraries, and these document libraries can also contain folders that operate in the same way as folders in the file system. As well as folders that are used for organizing user content, other folders contain files that are used by the SharePoint platform itself. These files often contain configuration files for platform elements such as content types.

The following code snippet shows how to enumerate folders within a SharePoint site. Folders used for organizational purposes have an attached DocumentLibrary object, whereas system folders do not.

void ListRootWebFolders()
{
  Console.WriteLine("Files in site collection root site:");
  using (SPSite site = new SPSite("YourSiteCollectionURL"))
  {
    using (SPWeb root = site.RootWeb)
    {
      listFolders(root.Folders);
    }
  }
}
void listFolders(SPFolderCollection folders)
{
  foreach (SPFolder folder in folders)
  {
    Console.Write(folder.Name + "\t");
    if (folder.DocumentLibrary != null)
    {
      Console.WriteLine("Corresponding library: " + folder.DocumentLibrary.Title);
    }
    else
    {
      Console.WriteLine(string.Empty);
    }
    listFolders(folder.SubFolders);
  }
}


					  

Saving Changes Using the Server Object Model

Behind the scenes, SharePoint, like many enterprise applications, stores all data within a database. Many of the objects that we’ve seen are actually an in-memory copy of the state of a particular component, and as a result, changing properties on the object affects only the in-memory copy and not the underlying database. To commit object changes to the database, the Update method should be called, as this snippet shows:

void UpdateDescription()
    {
      Console.WriteLine("Lists in site collection root site:");
      using (SPSite site = new SPSite("YourSiteColectionURL"))
      {
        using (SPWeb root = site.RootWeb)
        {
          root.Description = "My New Description";
          root.Update();
        }
      }
    }

Best Practice Guidelines

We’ve covered most of the commonly used objects in the Server Object Model. However, you should bear in mind a few caveats when using these objects.

IDisposable

Probably the most important thing to remember is that some of the objects that we’ve covered here implement the IDisposable interface, as you can see from the hierarchical diagram shown earlier. There is a very good reason for the objects to implement this interface specifically: these objects hold a reference to an SPRequest object, which in turn holds a reference to a COM component. The SharePoint platform uses the COM component to communicate with SQL Server. By implementing IDisposable, these objects can explicitly close the connection to the database and properly clean up the COM component when the .NET Framework objects are no longer required.

So what can we do to ensure that objects are disposed of properly? As a general rule, best practice is to wrap all IDisposable objects in a using block; you can see this technique used in the earlier examples. However, there are exceptions to this rule. On many occasions, IDisposable objects are passed into a function or are otherwise automatically created by the SharePoint platform. For example, the following code samples use a reference to an IDisposable object that was created by the platform:

private void UseSPContext(string myList)
{
  SPList list = SPContext.Current.Web.Lists.TryGetList(myList);
  if (list == null)
  {
    //Do Something
  }
}

When creating event handlers, the properties parameter contains a reference to the SPWeb object that has raised the event:

public override void ItemUpdating(SPItemEventProperties properties)
{
  string title = properties.Web.Title;
}

For situations in which the IDisposable object is created elsewhere, it is not appropriate to dispose of it explicitly since this could cause problems elsewhere.

Performance

A few common coding practices can lead to performance problems when you’re developing SharePoint applications. In addition to the IDisposable issues, which are by far the most common, most other problems relate to the proper use of data access.

You’ve seen how the SPList and SPListItem classes can be used to retrieve and represent data from a SharePoint content database. However, the SPListItem object is relatively heavyweight and as a result, if we retrieve the contents of a list that contains many items, the resource implications are significant.

The following code sample shows how we can use the SPQuery object to restrict the number of rows returned and then page through the items in a list.

SPQuery query = new SPQuery();
query.RowLimit = 20;
do
{
  SPListItemCollection items = myList.GetItems(query);
  //Use the items
  query.ListItemCollectionPosition = items.ListItemCollectionPosition;
} while (query.ListItemCollectionPosition != null);

Another common coding pattern that can cause performance issues is demonstrated in this code snippet:

SPList masterPages = root.Lists.TryGetList("Master Page Gallery");
if (masterPages != null)
    {
    foreach (SPListItem fileItem in masterPages.Items)
        {
          SPFile file = fileItem.File;
          Console.WriteLine(file.Name);
        }
}

Although this code works properly and would probably be our first choice when iterating through a collection of list items, behind the scenes, the implementation to the SPList object makes this a common cause of performance problems. Each time the Items collection is referenced, the underlying SPWeb object makes a call to the SQL database to retrieve the list of items. So if we imagine a list with 2000 items, iterating through the list using this code would generate 2000 database calls with each one returning 2000 rows. If a few users were performing the same actions at the same time, you can see how this quickly would become a major performance drain.

Thankfully, the problem is easy to fix:

SPList masterPages = root.Lists.TryGetList("Master Page Gallery");
if (masterPages != null)
    {
    SPListItemCollection items = masterPages.Items;
    foreach (SPListItem fileItem in items)
        {
          SPFile file = fileItem.File;
          Console.WriteLine(file.Name);
        }
}

By assigning the Items property to a SPListItemCollection variable and then using that as the target of our iteration, we’re generating only a single database query when the SPListItemCollection is assigned.

Error Handling

I’ve left error handling and boundary checking code out for the sake of brevity. Of course, in real-world code, we’d add these things and create suitable unit tests to validate their functionality. To make it possible for us to filter SharePoint specific errors in try/catch blocks, all SharePoint exceptions are derived from the SPException class.

Earlier we looked at Sysinternals DebugView as a tool to assist in debugging problems in server-side code. Although we could use this as an error logging tool, SharePoint provides a better way to achieve the same result. Using code similar to the following sample, we can write error logging entries to the SharePoint Unified Logging Service (ULS) logs:

try
  {
    //some code
  }
  catch (Exception ex)
  {
    SPDiagnosticsCategory myCat=new SPDiagnosticsCategory("A new category",
                                                        TraceSeverity.Monitorable,
                                                        EventSeverity.Error);
    SPDiagnosticsService.Local.WriteEvent(1, myCat,
                                        EventSeverity.Error,
                                        "My custom message",
                                        ex.StackTrace);
  }


					  
Other -----------------
- SQL Server 2008 R2 : Creating and Managing Stored Procedures - Viewing Stored Procedures
- SQL Server 2008 R2 : Creating and Managing Stored Procedures - Deferred Name Resolution
- Using Microsoft SharePoint with Microsoft Dynamics CRM Functions (part 2) - Displaying Data Using BDC in Microsoft Office SharePoint Server
- Using Microsoft SharePoint with Microsoft Dynamics CRM Functions (part 2) - Displaying Data Using BDC in Microsoft Office SharePoint Server
- Using Microsoft SharePoint with Microsoft Dynamics CRM Functions (part 1) - Displaying Data in SharePoint Using the List Web Part for Microsoft Dynamics CRM 4.0
- Microsoft Exchange Server 2007 : Single Copy Clusters (part 2) - Installing Exchange Server 2007 on the Active Node
- Microsoft Exchange Server 2007 : Single Copy Clusters (part 1)
- Windows Server 2003 on HP ProLiant Servers : Logical Structure Design (part 5) - Trust Definitions
- Windows Server 2003 on HP ProLiant Servers : Logical Structure Design (part 4) - Group Policy
- Windows Server 2003 on HP ProLiant Servers : Logical Structure Design (part 3) - Naming Standards
 
 
REVIEW
- First look: Apple Watch

- 10 Amazing Tools You Should Be Using with Dropbox

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
 
VIDEO TUTORIAL
- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
 
Popular tags
Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8 BlackBerry Android Ipad Iphone iOS
Popular keywords
HOW TO Swimlane in Visio Visio sort key Pen and Touch Creating groups in Windows Server Raid in Windows Server Exchange 2010 maintenance Exchange server mail enabled groups Debugging Tools Collaborating
Top 10
- Microsoft Excel : How to Use the VLookUp Function
- Fix and Tweak Graphics and Video (part 3) : How to Fix : My Screen Is Sluggish - Adjust Hardware Acceleration
- Fix and Tweak Graphics and Video (part 2) : How to Fix : Text on My Screen Is Too Small
- Fix and Tweak Graphics and Video (part 1) : How to Fix : Adjust the Resolution
- Windows Phone 8 Apps : Camera (part 4) - Adjusting Video Settings, Using the Video Light
- Windows Phone 8 Apps : Camera (part 3) - Using the Front Camera, Activating Video Mode
- Windows Phone 8 Apps : Camera (part 2) - Controlling the Camera’s Flash, Changing the Camera’s Behavior with Lenses
- Windows Phone 8 Apps : Camera (part 1) - Adjusting Photo Settings
- MDT's Client Wizard : Package Properties
- MDT's Client Wizard : Driver Properties
 
Windows XP
Windows Vista
Windows 7
Windows Azure
Windows Server
Windows Phone
2015 Camaro