Understanding Key Design Decisions in SharePoint 2010 Development

Summary:  Learn about important design decisions that you must make when you are planning and developing business solutions for Microsoft SharePoint 2010.

Applies to: Business Connectivity Services | Office 2010 | Open XML | SharePoint Designer 2010 | SharePoint Foundation 2010 | SharePoint Online | SharePoint Server 2010 | Visual Studio

Provided by:  Ted Pattison (SharePoint MVP), Critical Path Training | About the Author

Contents

  • Overview of SharePoint 2010 Design Decisions

  • SharePoint 2010 as a Development Platform

  • Deploying SharePoint Solution Packages as Farm Solutions vs. Sandboxed Solutions

  • Designing the UI by Using Web Parts, Site Pages, or Application Pages

  • Server Object Model vs. Client Object Model in SharePoint 2010

  • Accessing List-Based Content in SharePoint Sites

  • Choosing Between JavaScript and Silverlight

  • Conclusion

  • Additional Resources

  • About the Author

Overview of SharePoint 2010 Design Decisions

This article discusses key design decisions that you must make when you are architecting and developing business solutions for Microsoft SharePoint 2010. You will learn when it makes sense to create SharePoint solutions that target the sandbox and when to create SharePoint solutions that support only farm-level deployment. The article also explains how to choose between Web Parts, site pages, and applications when you are building a SharePoint solution that requires a custom user interface (UI). You will also learn how to decide between using the server-side object model and client object model, and how to choose the appropriate technique for accessing content in a SharePoint list.

SharePoint 2010 as a Development Platform

SharePoint technologies have gone through four major product releases. Both the first release in 2001 and the second release in 2003 experienced favorable yet modest levels of adoption. However, it was with the third release in 2007 that SharePoint technologies really began to take off with a rapid adoption rate. Microsoft Office SharePoint Server 2007 has been deployed by thousands of businesses, organizations, and government agencies around the world. SharePoint 2010 improves upon the 2007 release by introducing new features and services, which gives SharePoint technologies a bright future for continued growth.

As SharePoint technologies have increased in popularity over the years, so has the desire to customize the built-in experience using custom SharePoint solutions. Moreover, Microsoft has continued to invest in SharePoint technologies to transform it into a first-class development platform. With the 2003 release, Microsoft first made it possible to extend a SharePoint site by using custom Microsoft .NET Framework components, such as Web Parts and event handlers that are written by using C# or Microsoft Visual Basic. In the 2007 release, Microsoft revamped SharePoint as a development platform by introducing essential developer-oriented building blocks, such as content types, site columns, Features, and solution packages.

Although many new aspects of SharePoint 2010 advance the SharePoint developer platform, the one that is arguably the most significant is the new tool set known as the SharePoint development tools in Microsoft Visual Studio 2010. The SharePoint development tools in Visual Studio 2010 represent a great step ahead because they hide and automate many tedious aspects of SharePoint development, such as generating a solution package from the source files in a SharePoint project. The SharePoint development tools in Visual Studio 2010 also provide the convenience of deploying the solution package for a SharePoint project into the local farm so that you can test and debug your code on a development workstation.

The SharePoint development tools in Visual Studio 2010 are great for beginners and .NET developers who are just starting with SharePoint development because it enables them to get up to speed and become productive quickly. The SharePoint development tools in Visual Studio 2010 were also designed to be extensible, which lets experienced SharePoint developers use advanced development techniques that are not directly supported by the tool set itself.

The SharePoint 2010 development platform introduces several other advancements beyond the new support in Visual Studio 2010. For example, SharePoint 2010 lets you deploy a solution package as either a farm solution or as a sandboxed solution. SharePoint 2010 introduces a new client object model to complement the server-side object model that has been part of the SharePoint development platform since the 2003 release. SharePoint 2010 also introduces new options for accessing content in a SharePoint list, including LINQ (Language Integrated Query) support and a REST-based web service.

Although it's nice to have options, you can never use them all. Instead, you must choose among these options each time you begin to design a new SharePoint solution for a particular scenario. The next sections describe the most relevant design issues to consider so that you can make the best choices when you design and develop new SharePoint solutions.

Deploying SharePoint Solution Packages as Farm Solutions vs. Sandboxed Solutions

An essential concept in SharePoint development is that of the solution package. At a physical level, a solution package is a CAB archive that contains the files and the metadata that are required to deploy a custom development effort in a SharePoint environment. From a design standpoint, a solution package is the atomic unit for reuse, testing, and deployment. The solution package also provides the granularity at which updates can be pushed out into a SharePoint farm to fix bugs and extend a custom solution that is already deployed.

There are two ways in which you can deploy a solution package in SharePoint 2010: as a farm solution or as a sandboxed solution. Each time you create a new SharePoint project by using the SharePoint development tools in Visual Studio 2010, you are forced to choose whether to develop and test your code as a sandboxed solution or as a farm solution. Your decision should be based on whether you want to develop and test the SharePoint solution to support farm-level deployment only, or whether you want to test it as a SharePoint solution that provides the flexibility to deploy it as either a farm solution or a sandboxed solution.

A solution package that is deployed as a farm solution must be deployed by a farm administrator. Because farm solution deployment requires copying custom files to each web server in the farm, it poses certain risks to the health of the farm. Furthermore, most farm solutions install custom assembly DLLs in the global assembly cache on the web server, which allows the code inside to run at a level of full trust. Therefore, many farm administrators require SharePoint solutions to undergo lengthy code reviews and rigid testing procedures before the solutions are deployed in a production farm. Farm administrators in some SharePoint environments go one step further and prohibit farm-level deployment of SharePoint solutions altogether.

SharePoint 2010 introduces new sandboxing architecture that provides a valuable alternative to farm-level deployment. Unlike farm solution deployment, sandboxed solution deployment does not require the approval or assistance of a farm administrator. Instead, a SharePoint solution that was developed as a sandboxed solution can be uploaded and activated by a business user in the role of a site collection owner or a site administrator. This can significantly speed up the process of getting a custom SharePoint solution into service. Sandboxed solutions also make it possible to develop custom solutions that target environments that do not allow for farm solution deployment, such as SharePoint Online.

There is an important point about the new sandbox architecture that is often misunderstood. Just because you design and develop a SharePoint solution as a sandboxed solution does not mean that you always have to deploy it as a sandboxed solution. Instead, you can deploy a SharePoint solution that is developed to target the sandbox as either a sandboxed solution or as a farm solution. This means that developing a SharePoint solution as a sandboxed solution provides more flexibility in various deployment scenarios.

Let's look at an example of how a sandboxed solution provides this flexibility. In a SharePoint farm that does not allow for farm-level solution deployment, users who have site administrator permissions can upload and activate your SharePoint solution within the context of a site collection. In another SharePoint farm that does not pose these restrictions, the same SharePoint solution can be deployed as a farm solution, which makes it possible to obtain higher levels of performance and maintainability. This provides a design motivation for targeting the sandbox whenever the constraints of the sandbox don't prevent you from accomplishing what you need to.

Limitations of Sandboxed Solutions

When you are deciding whether you should develop a SharePoint solution as a sandboxed solution, it is critical that you understand what is allowed and what is prohibited in the sandbox. For example, a sandboxed solution is restricted from deploying files to the file system of the web server. This means that a sandboxed solution cannot include any of the following:

  • Assemblies installed in the global assembly cache

  • Features that activate at the farm level

  • Features that activate at the web application level

  • Application pages

  • User controls

  • Visual Web Parts

  • Sequential Workflow templates

  • State Machine Workflow templates

  • Business Data Connectivity (BDC) service models

There are also important restrictions in what you can do with server-side code. Although a sandboxed solution can contain code that uses the server-side object model, many parts of the server-side object model are off limits. For example, code in a sandboxed solution cannot access anything in the server-side object model that is outside the scope of the current site collection. You cannot create new objects by using the SPSite class to access other site collections. Furthermore, you are not allowed to access any farm-level aspects of the server-side object model such as a SPFarm object or a SPWebApplication object.

The following list shows common programming tasks that can be accomplished only when you deploy code in a farm solution:

  • Creating and configuring web applications

  • Creating and configuring content databases

  • Creating site collections

  • Aggregating content stored in two or more site collections

In addition to the programming restrictions on the server-side object model, you are further restricted by the sandbox architecture from using many of the class libraries that are provided by the Microsoft .NET Framework. SharePoint Foundation enforces these restrictions by running sandboxed code in an isolated worker process that is initialized by using code access security (CAS) settings. For example, you cannot access any of the classes in the System.IO namespace. Furthermore, the server-side code in a sandboxed solution cannot access any parts of the .NET Framework that enable you to access resources from across the network. This means you cannot connect to a database, make an outbound web service call, or even issue a simple HTTP GET request.

As you can see, the sandbox places significant restrictions on what you can do in server-side code. The only place where your code can access content is from within the site collection where the sandboxed solution has been uploaded and activated. These restrictions can force you to rethink your design when you are developing SharePoint projects in which you need to access resources from across the network, such as web services and databases.

In scenarios that require access to network resources, it might make sense to choose a farm solution instead of a sandboxed solution. However, there is one other option to consider. Although the sandboxed solution architecture restricts what server-side code can do, it does not place any restrictions on client-side code. Therefore, you can design a sandboxed solution by using client-side code written in ECMAScript (JavaScript, JScript) or a Microsoft Silverlight application that can access network resources. We will continue to discuss the design option throughout this article.

Common Development Scenarios for Sandboxed Solutions

The restrictions placed on sandboxed solutions are often too limiting for many types of SharePoint projects. However, there are a few categories of simple business solutions that can be fully implemented by using sandboxed solutions. The following is a list of requirements that can be met by using a sandboxed solution:

  • Creating custom site columns, content types, and list definitions

  • Creating lists and adding event handlers for data validation

  • Creating navigation nodes on the Quick Launch menu and top navigation bar

  • Adding Web Parts that query and update lists

  • Adding site pages to host Web Parts and Silverlight applications

  • Branding SharePoint sites with custom master pages, CSS files, and images

Designing the UI by Using Web Parts, Site Pages, or Application Pages

There are important design issues to consider as you design the UI in a SharePoint project. For example, should you create UI elements by using Web Parts, site page templates, or application pages? Each of these three techniques for creating custom UI elements has advantages over the other two in certain scenarios. However, you can find other scenarios where each approach works just fine, which means that the decision comes down to a personal preference on the part of a developer.

Think through the design scenario at hand, and ask yourself the following questions:

  • Do you need to support user customization and personalization?

  • Are you worried about giving users too much control?

  • Does the UI require server-side code written in C# or Visual Basic?

  • Will you be required to deploy the UI by using a sandboxed solution?

Supporting User Customization of Webpages

Let's begin with the first question—whether you need to support user customization and personalization. If so, the best choice is to build out the UI by using Web Parts. This is because SharePoint Foundation gives users the ability to add, customize, personalize, and delete Web Parts. Many users who have experience with SharePoint technologies are very adept at adding Web Parts to pages and customizing them through the task pane in the browser.

Site pages also provide a degree of user customization support, but it is not as straightforward as it is with Web Parts. For example, a user cannot customize the underlying content for site pages by using the browser. Instead, a user must rely on a SharePoint-compatible page editing tool, such as Microsoft SharePoint Designer 2010. However, you should understand that modifying site pages by using SharePoint Designer 2010 requires an understanding of complex topics, such as HTML editing, server-side controls, and master pages. Therefore, site page customization should be limited to scenarios that involve advanced users who are skilled in designing SharePoint pages by using SharePoint Designer 2010.

If you decide to build your UI by using Web Parts, you should consider how these Web Parts will be added to pages in a SharePoint site. The simplest approach involves creating Web Parts and nothing more. This is a fairly common scenario where users are required to add instances of your Web Parts to existing Web Parts pages. A more polished approach involves automating the work of adding your Web Parts to site pages during feature activation.

When you create Web Parts in a SharePoint solution, you should consider whether it makes sense to also create pages to host your Web Parts. If you decide that it does make sense, you cannot use application pages because they do not support Web Parts. Instead, you must design one or more site page templates that meet the requirements of a Web Parts page. After you create the site page template, you can add it to a module in a SharePoint solution to create a new site page instance during Feature activation. The final step is to prepopulate the site page with instances of your Web Parts. You can do this by adding an AllUserWebPart element inside the File element, which creates the site page during Feature activation.

Controlling UI Customization

Now let's consider the second question. Are you worried about giving the user too much control on a site? Many developers fear the careless user who likes to experiment and often gets into trouble. For example, imagine your UI design involves a site page with a Web Part. What is there to prevent a privileged and misguided user from placing the page into edit mode and then deleting the Web Part? You can imagine how this could result in calls to the support line and the SharePoint site being unusable for a period of time until someone who has more technical skills can step in and add the appropriate Web Part back to the page.

Application pages do not support any form of user customization. Therefore, they can be advantageous to use in designs where you want to lock the UI. Trying to lock down a UI that is built with site pages and Web Parts can be tedious and often becomes impractical in scenarios where users have site owner permissions.

Using Server-Side Code Behind the UI

The next question to think about is whether you need to write server-side code behind your UI. If this is the case, you must choose either Web Parts or application pages. More specifically, you should avoid writing server-side code in site page and site page templates. That is because site pages must support safe mode processing, which prohibits inline code written in C# or Visual Basic. Although technically you can create a custom base class by using C# or Visual Basic and inherit from this base class from site page templates, this approach is not recommended. It can become cumbersome and is rarely used in SharePoint development because it is much easier to add server-side code to Web Parts or behind application pages.

Deploying the UI as a Sandboxed Solution

Another important question to consider when you design a custom UI is whether you want to support deployment as a sandboxed solution. If this is the case, you must avoid using application pages that cannot be properly deployed by a sandboxed solution. This means that you must construct your UI by using site pages and Web Parts.

Server Object Model vs. Client Object Model in SharePoint 2010

Since the 2003 release, SharePoint has provided developers with a server-side object model to access content within a site and to perform various administrative tasks at the site level, such as creating lists, adding navigation nodes, and configuring permissions. The server-side object model also makes it possible to perform administrative tasks at the farm level, such as creating and configuring web applications and content databases.

The server-side object model is made available through an assembly named Microsoft.SharePoint.dll, which is deployed on every server in a SharePoint farm. This means that the server-side object model is available to you whenever you are developing SharePoint components that run on the web server, such as Feature receivers, event handlers, Web Parts, application pages, and workflow templates. However, the server-side object model is not directly available to applications and components that run on computers that are not part of a SharePoint farm.

SharePoint 2010 introduces a new client object model that enables access to SharePoint sites from across the network. For example, you can use the client object model to write code in a desktop application that can connect to a SharePoint site across the network. After you connect to a SharePoint site by using the client object model, you can read and update content in lists and document libraries. You can also perform administrative chores within a site, such as creating new lists, adding navigation nodes, and configuring user permissions.

The client object model can be used effectively in several types of applications. For example, the client object model makes it possible to develop desktop applications by using Windows Forms and Windows Presentation Foundation (WPF) that read and write content from SharePoint sites. The client object model is also very useful for writing client-side code that runs behind pages inside the browser, such as custom JavaScript code or a Silverlight application.

A key benefit to using the client-side object model is that it can significantly improve the user experience. That is because you can write code that executes on the user's computer, which eliminates the need for postbacks and confusing page transitions. For example, you can write client-side code behind a command button to update a list item in a SharePoint site, and then to refresh the UI to reflect that change. The important part is that you can perform this work without forcing the user to endure a page transition or a postback.

How Does the SharePoint Client Object Model Work?

The client object model in SharePoint 2010 is built on top of Windows Communication Foundation (WCF), which is used to establish communications between the client computer and the web server. SharePoint Foundation provides an entry point into the client object model on each web server in the farm by using a WCF web service file named Client.svc.

It is important to be aware that you do not have to understand how WCF works in order to use the client object model. In fact, the client object model was specifically designed to hide the underlying details of the WCF plumbing from SharePoint developers. When you use the client object model, you create objects and access their methods and properties. The client object model provides a client-side runtime that handles communicating with the web server by using WCF web service calls.

The client object model can be accessed from three types of client applications, including .NET Framework applications, Silverlight applications, and JavaScript code that runs within a page in a SharePoint site. If you are developing a .NET Framework application, you can access the client object model by referencing the following assemblies:

  • Microsoft.SharePoint.Client.dll

  • Microsoft.SharePoint.Client.Runtime.dll

Notice that these two assemblies must also be deployed in additional to any .NET Framework application that uses the client object model. A .NET Framework application that is written by using the client object model cannot run correctly if it cannot load the two assemblies at run time.

If you are developing a Silverlight application, you can access the client object model by referencing the following assemblies:

  • Microsoft.SharePoint.Client.Silverlight.dll

  • Microsoft.SharePoint.Client.Silverlight.Runtime.dll

Notice that these two assemblies must be available to load into the process of the browser whenever a Silverlight application starts to use the client object model. However, the steps for deploying these two assemblies are automatically handled by Visual Studio 2010. When you create a new Silverlight project and add references to these assemblies, Visual Studio 2010 configures the project's build process to automatically embed these two assemblies into the .xap file that is used to deploy the Silverlight application. This enables you to deploy these assemblies with any Silverlight application that depends on them.

Now it is time to discuss using the client object model from custom JavaScript code. If you are writing client-side JavaScript code on a page in a SharePoint site, you can access the JavaScript client object model through a standard library file named sp.js that is deployed on each web server in the farm. Before you start to use the JavaScript client object model, you must ensure that sp.js has been downloaded and made available to the page. You can do this in JavaScript by calling the ExecuteOrDelayUntilScriptLoaded method and passing the custom function name and the file name of sp.js.

ExecuteOrDelayUntilScriptLoaded(MyJavaScriptCode, "sp.js");

function MyJavaScriptCode() {

  // This code will not execute until sp.js is fully downloaded.
}

Note

Many of the standard JavaScript library files in SharePoint, such as sp.js, are configured to load on demand after the page has already been shown to the user. This new lazy loading technique was introduced in SharePoint 2010 to provide a more responsive UI experience. However, lazy loading also raises a concern for developers. The problem is that you will experience a runtime error if you try to access anything inside sp.js if the file has not been downloaded to the browser.

The call to ExecuteOrDelayUntilScriptLoaded forces the hosting page to download sp.js entirely before attempting to execute the custom function. This is an example of one technique that can be used to ensure your client-side JavaScript code can successfully make calls into sp.js and begin using the client object model.

Executing Client Object Model Methods Asynchronously

When you start to use the client object model, you often find that you cannot execute methods against the web server by using synchronous behavior. This is because a synchronous call ties up the primary UI thread and results in freezing the UI until the method call returns. It is generally unacceptable in application design to freeze the UI when making calls across the network. Therefore, you must learn how to execute methods against the web server asynchronously.

For example, when you are developing a Silverlight application that uses the client object model, you should always call to the web server asynchronously by using the ExecuteQueryAsync method. When you call the ExecuteQueryAsync method, you must pass delegate references to callback methods. These callback methods execute when the call returns from the web server. The following code example demonstrates a simple Silverlight application that was written to interact with the web server asynchronously.

public partial class MainPage : UserControl {
  protected ClientContext clientContext;
  protected Web site;

  public MainPage() {
    InitializeComponent();
    clientContext = new ClientContext("http://intranet.wingtip.com");
    site = clientContext.Web;
    clientContext.Load(site);
    clientContext.ExecuteQueryAsync(OnSucceed, OnFail);
  }

  void OnSucceed(object sender, ClientRequestEventArgs args) {

    // Callback method that executes when there are no errors.
  }

  void OnFail(object sender, ClientRequestEventArgs args) {

    // Callback method that executes when there are errors.
  }
}

Another challenge for the developer involves writing code in callback methods to handle thread switching. This is required when you are using the client object model because callback methods are executed on secondary threads, which cannot access controls in the UI, such as text boxes and data grids. They key point is that the developer is responsible for switching the execution flow from secondary threads back to the primary UI thread. After execution is switched over to the primary UI thread, it is possible to update controls. The following is an example of thread switching by using the Dispatcher.BeginInvoke method in a Silverlight application to update a textbox control.

void OnSucceed(object sender, ClientRequestEventArgs args) {

  // Running on secondary thread.
  Dispatcher.BeginInvoke(delegate() {

    // Running on primary UI thread.
    txtDisplay.Text = "Site ID = " + site.Id.ToString();
  });
}

From these examples, you can get a sense that using the client object model requires a high level of programming skill. Therefore, developing with the client-side object model might be more appropriate for advanced developers than for beginners.

Accessing List-Based Content in SharePoint Sites

SharePoint 2010 provides you with several different options for accessing list-based content in a SharePoint site. You can access items in a list in server-side code using an SPQuery object or an SPSiteDataQuery object. You can also decide to write server-side code that queries and updates list items using the new LINQ to SharePoint support. When it comes to writing client-side code, you have two more options with the client object model and a new REST-based web service. This sections describes each of these techniques and discusses their relative strengths and weaknesses.

In the 2003 release, Microsoft introduced the SPQuery class in the server-side object model to provide a means to query items in a SharePoint list. Using the SPQuery class requires the developer to parse together XML fragments to parameterize the query in a language known as Collaborative Application Markup Language (CAML). The following is a typical example of what is required to execute a query against a SharePoint list by using an SPQuery object.

SPList contacts = this.Web.Lists["Contacts"];
SPQuery query = new SPQuery();
query.ViewFields = "<FieldRef Name='Title'/>" + 
                    "<FieldRef Name='FirstName'/>" +
                    "<FieldRef Name='Email'/>" +
query.Query = @"<Where>
                  <BeginsWith>
                    <FieldRef Name='FirstName'/>
                    <Value Type='Text'>B</Value>
                  </BeginsWith>
                </Where>
                <OrderBy>
                  <FieldRef Name='Title'/>
                  <FieldRef Name='FirstName'/>
                </OrderBy>";

SPListItemCollection results = contacts.GetItems(query);
foreach (SPListItem item in results) {

  // Enumerate through items.
  string FirstName = item["FirstName"].ToString()
}

The SPQuery class is useful because it provides an efficient way to run queries against large lists when you write server-side code. The primary disadvantage of using the SPQuery object relates to developer productivity. Visual Studio 2010 provides no assistance in parsing together the required CAML fragments. This often leads developers to inefficient reuse techniques based on frequent copying and pasting CAML fragments from working samples. However, there is still the problem that access to column values is not strongly typed. Instead, you must read and write column values by passing the column name as a string.

string s = item["Title"].ToString()

The lack of a strongly typed technique for accessing the column values in a list creates a few noteworthy disadvantages. Neither the C# compiler nor the Visual Basic compiler can determine when a column name is spelled incorrectly. The compiler also cannot determine whether the developer is correctly converting column values to their correct types. This results in bugs that can be found only in the testing phase. The lack of strongly typed column access also makes it impossible for Visual Studio 2010 to provide any assistance through IntelliSense when choosing which column to access.

In the 2007 release, Microsoft added the SPSiteDataQuery class to complement the SPQuery class. The SPSiteDataQuery class lets developers execute queries that aggregate items from multiple lists into a single result set. For example, imagine you want to run a single query that could find and aggregate together the contacts from all the contacts lists within the current site collection. You can run the following query by using an SPSiteDataQuery object that sets the query scope to the current site collection and provides a where clause that is based on the Contact content type.

SPSiteDataQuery query = new SPSiteDataQuery();
query.Webs = "<Webs Scope='SiteCollection' />";
query.ViewFields = "<FieldRef Name='Title'/>" + 
                   "<FieldRef Name='FirstName'/>" +
                   "<FieldRef Name='Email'/>";
query.Query = @"<Where>
                  <FieldRef Name='ContentType'/>
                  <Value Type='Computed'>Contact</Value>
                </Where>";
DataTable results = this.Web.GetSiteData(query);
foreach (DataRow item in results.Rows) {

  // Enumerate through items.
  string FirstName = item["FirstName"].ToString()
}

The ability to run queries that aggregate items from multiple lists definitely gives SPSiteDataQuery unique capabilities over the other list access techniques. Consequently, it is useful to SharePoint developers in scenarios that call for aggregation. However, the SPSiteDataQuery class has the same developer productivity disadvantages as the SPQuery class because it forces the developer to parse together CAML fragments, and it does not provide strongly typed access to column values.

Another potential problem with the SPSiteDataQuery class is that it can result in inefficient queries that take a long time to run and that consume a significant number of processing cycles from the web server. Therefore, you should make sure you perform adequate performance testing whenever you use the SPSiteDataQuery class. You should also consider avoiding using the SPSiteDataQuery class behind pages that are frequently accessed, such as the home page for a site.

Using LINQ to SharePoint Provider Support

Microsoft introduced support in SharePoint 2010 that makes it possible for server-side code to execute a query against SharePoint lists by using LINQ (Language Integrated Query). The support is implemented by the LINQ to SharePoint provider that is installed as a standard component in SharePoint Foundation.

The primary advantage to accessing items in a SharePoint list by using the LINQ to SharePoint provider is the increase in developer productivity. When you access a SharePoint list by using LINQ, there is no need for you to work with CAML. Instead, you write where clauses and order by clauses directly in C# or Visual Basic.

Using LINQ also makes it possible to program against column values in a strongly typed manner. This allows the compiler to generate errors when the developer has made a mistake with respect to the name or type of a column. The strongly typed nature of LINQ also enables Visual Studio 2010 to provide IntelliSense with a drop-down list that shows all the available columns in a list.

Examine the following code written to execute a LINQ query against a SharePoint list, and compare it to the examples shown earlier that use CAML.

WingtipSiteDataContext dc = new WingtipSiteDataContext(this.Web.Url);
var query = from contact in dc.Contacts
            where contact.FirstName.StartsWith("B")
            orderby contact.LastName
            select contact;
foreach (var item in query) {

  // Enumerate through items.
  string FirstName = item.FirstName;
}

The LINQ to SharePoint provider also increases developer productivity when new items are added to a SharePoint list. As in the case of querying list items, the LINQ to SharePoint provider enables strong typing and IntelliSense when you assign column values to a new list item. The following is an example of adding a new list item by using LINQ support.

WingtipSiteDataContext dc = new WingtipSiteDataContext(this.Web.Url);
Contact newContact =
  new Contact {
    FirstName = "Wendy",
    LastName = "Wheeler"
    EMail = "wendy@wheeler.com"
  };
dc.Contacts.InsertOnSubmit(newContact);
dc.SubmitChanges();

As you can see, the LINQ to SharePoint provider offers definite advantages to developers who are required to query and update SharePoint list items. However, you should understand that the LINQ to SharePoint provider really just represents a productivity layer on top of CAML. Behind the scenes, the LINQ to SharePoint provider is translating LINQ query statements into CAML and then using CAML to execute these queries against the content database. Therefore, there isn't really anything you can do with the LINQ to SharePoint provider that you cannot do using CAML together with the SPQuery class or the SPSiteDataQuery class. However, the opposite is not true. You can do several things with the SPQuery class and the SPSiteDataQuery class that you cannot accomplish by using LINQ.

One issue with using the LINQ to SharePoint provider is that you must know how the columns look in advance. Before you write code that uses LINQ to SharePoint provider, you must first run the spmetal.exe utility to generate the entity classes that are required in LINQ programming. This makes it impossible to use LINQ in scenarios where your code must discover the names and types of the columns in a list at run time.

Another issue is that the LINQ to SharePoint provider does not support any behavior to match the SPSiteDataQuery class and its ability to run queries that aggregate items together from multiple lists throughout a site collection. Instead, you must run multiple queries by using the LINQ to SharePoint provider and then write your own code to aggregate the results into a single result set.

One final note about the LINQ to SharePoint provider is that it does not currently provide a way to disable throttling. That means that queries that are executed by using the LINQ to SharePoint provider run the risk of failure when the number of items returned would exceed the throttling threshold for the current web application. This is no limitation when you are executing queries with the SPQuery class or the SPSiteDataQuery class because you can disable throttling by setting the QueryThrottleMode property to a value of Override.

SPQuery query = new SPQuery();
query.QueryThrottleMode = SPQueryThrottleOption.Override;

We have now addressed the techniques that are used to access SharePoint lists by using server-side code. However, certain SharePoint design scenarios are better suited for client-side code instead of server-side code. Therefore, you should also know what your options are for querying SharePoint list items from across the network. One option you have is to access SharePoint lists by using the client object model. A second option is to use the new REST-based web service that is included with SharePoint Foundation. The next section examines these two techniques to see how they compare with the server-side techniques you just learned about.

Accessing List Items Using the SharePoint Client Object Model

The client object model provides a wide range of functionality for what can be accomplished inside a site collection. For example, you can write code by using the client object model that adds users, creates lists, and configures permissions. In addition to this type of functionality, the client object model also provides the ability to read and write list items.

The client object model support for querying list items is made available through the CamlQuery class. As its name suggests, running queries with CamlQuery requires you to work in terms of CAML, as shown in the following example.

clientContext = new ClientContext("http://intranet.wingtip.com");
site = clientContext.Web;
clientContext.Load(site);
List contactsList = site.Lists.GetByTitle("Contacts");
clientContext.Load(contactsList);
CamlQuery query = new CamlQuery();
query.ViewXml = @"<View>
                    <Query>
                      <FieldRef Name='Title' />
                      <FieldRef Name='FirstName'/>
                      <FieldRef Name='Email'/>
                      <Where>
                        <BeginsWith>
                          <FieldRef Name='FirstName'/>
                          <Value Type='Text'>B</Value>
                        </BeginsWith>
                      </Where>
                    </Query>
                  </View>";
ListItemCollection contactsCollection;
contactsCollection = contactsList.GetItems(customersQuery);
clientContext.Load(contactsCollection);
clientContext.ExecuteQueryAsync(OnSucceed, OnFail);

Querying and updating list items by using the client object model has some of the same disadvantages as working with the SPQuery class and the SPSiteDataQuery class. That is, you are required to parse together CAML fragments. That means that any errors in your CAML fragments cannot be caught by the compiler. Furthermore, you do not get any IntelliSense to assist you when you write queries.

Accessing SharePoint List Items Using REST-Based Web Services

The last technique for querying and updating list items involves using a new REST-based web service that is built into SharePoint Foundation. This REST-based web service is exposed by using a WCF web service file named ListData.svc, which can be accessed through the _vti_bin directory. ListData.svc makes it possible to access items in a SharePoint list by using a simple HTTP GET request based on a site-relative URL that includes the list title at the end, as shown in the following example.

http://intranet.wingtip.com/\_vti\_bin/ListData.svc/Contacts

One benefit of using a REST-based web service is that it can be accessed from almost any type of client, including the browser. Another related benefit is that any command can be parameterized into the target URL by appending a query string. When you create a URL to access list items from ListData.svc, you can add QueryString parameters to select the fields and also control filtering and ordering, as shown in the following examples.

ListData.svc/Contacts()?$select=FirstName,LastName

ListData.svc/Contacts()?$filter=startswith(FirstName, 'B')

ListData.svc/Contacts()?$orderby=FirstName

Another big benefit to using ListData.svc is that it generates XML responses that conform to emerging web protocols, such as the Atom Publishing Protocol (AtomPub) and the Open Data Protocol (OData). Standardization on OData as a protocol between clients and web services is becoming increasing popular within Microsoft and throughout the industry. Its popularity is due to its ability to create a simple and standardized way to expose and access content from a variety of data sources, such as relational databases, file systems, standard websites, and as of now, SharePoint lists.

It is also significant that the SharePoint team implemented the REST-based web service by using WCF Data Services. The SharePoint integration with WCF Data Services adds value because it gives you a way to retrieve SharePoint list items by using LINQ query statements. In addition, it lets you access column values by using strongly typed properties. This results in a developer experience that is similar to using the LINQ to SharePoint provider because the compiler and IntelliSense provide extra assistance when you write queries.

To create a service reference in a Visual Studio 2010 project, you must pass a site-relative URL that points to ListData.svc. When Visual Studio 2010 creates the service reference from ListData.svc, it generates code that contains a data context class for the site and a LINQ-compatible entity class for each list. The data context class exposes a property for each list based on the DataServiceQuery class, which makes it possible to execute remote queries by using LINQ query statements, as shown in the following example.

String url = "http://intranet.wingtip.com/_vti_bin/ListData.svc";
WingtipSiteDataContext dc = new WingtipSiteDataContext(new Uri(url));
var query = from contact in dc.Contacts
            where contact.FirstName.StartsWith("B")
            select contact;
foreach (var item in query) {

  // Strongly typed access to column value.
  string FirstName = item.FirstName;
}

If you plan to call ListDava.svc from JavaScript code or from a Silverlight application that is running inside the browser, you must also learn how to execute queries asynchronously. The following is an example of a Silverlight application that executes a remote query asynchronously by using a service reference created against ListDava.svc.

public partial class MainPage : UserControl {
  String url = "http://intranet.wingtip.com/_vti_bin/ListData.svc";
  protected WingtipSiteDataContext dataContext;
  protected DataServiceQuery<ContactsItem> ContactsQuery;

  public MainPage() {
    InitializeComponent();
    dataContext = new WingtipSiteDataContext(new Uri(url)); 
    ContactsQuery = 
         (from contact in dataContext.Contacts
          where contact.FirstName.StartsWith("B")
          select contact) as DataServiceQuery<ContactsItem>;
    ContactsQuery.BeginExecute(DisplayContacts, null);
  }

  public void DisplayContacts(IAsyncResult result) {
    Dispatcher.BeginInvoke(delegate(){
      var queryResults = ContactsQuery.EndExecute(result);
      foreach (var contact in queryResults) {

        // Access columns using strongly typed properties.
        string FirstName = customer.FirstName;
      }       
    });
  }
}

Notice that the DisplayContacts callback method is implemented to perform a thread switch by using the Dispatcher.BeginInvoke method that was discussed earlier. Executing queries asynchronously against ListData.svc is similar to using the client object model in that you must switch the execution of the callback method back over the primary thread before you update any controls in the UI.

Choosing Between JavaScript and Silverlight

In modern web application design, the requirement to add client-side code is becoming increasing popular. After all, websites that have rich client-side behaviors are now the norm on the Internet. Adding client-side code into your SharePoint solutions is definitely something that will improve the user experience.

Beyond improving the user experience, there are SharePoint design scenarios where client-side code can do what server-side code cannot. Let's examine a simple example. Imagine a scenario in which you are required to develop a sandboxed solution that retrieves content from a public web service on the Internet and then writes this content into a SharePoint list. The problem with using server-side code in a sandboxed solution is that you cannot call out to a web service.

However, you can redesign your sandboxed solution to include custom JavaScript code or a Silverlight application that calls out to the web service directly from the user's browser. After your client-side code retrieves the content from the web service, it can then write the content into a SharePoint list by using either the client object model or ListData.svc. This example provides yet another motivation for why you might want to include client-side code in a SharePoint solution.

If you decide you want to add client-side code to a SharePoint solution, the next step is to choose between writing custom JavaScript code-behind pages or developing one or more Silverlight applications. Let's look at the pros and cons of each approach.

JavaScript has an advantage of reach over Silverlight because it is supported across a larger number of browsers. Furthermore, browsers include built-in support for JavaScript, whereas Silverlight applications do not run unless the user downloads and installs the Silverlight runtime. Although the download and installation of the Silverlight runtime can be completed over the Internet in a matter of seconds, you must still acknowledge that Silverlight development makes an assumption that the user will trust a Microsoft software component and install it from across the Internet. This might not be a good assumption to make in wide-reach scenarios, such as when you develop a commerce application for the Internet where you want to reach the maximum number of potential users.

In most SharePoint 2010 environments, you can typically assume that it will not cause problems to deploy Silverlight applications with your SharePoint solutions. After all, SharePoint Foundation includes several different Silverlight 3 applications in standard pages, such as the creation page that is available by selecting the More Options command on the Site Actions menu.

The fact that SharePoint 2010 users are required to install Silverlight 3 just to get the complete built-in experience means that you can typically assume that they will already have the Silverlight 3 runtime installed on their computers. If you plan to use Silverlight 4 instead of Silverlight 3, you must assume that users are willing and able to install an updated version of Silverlight on their computers.

The final point to consider when choosing between JavaScript and Silverlight concerns developer productivity. In this area, Silverlight development is the clear winner. That is because you can work inside Visual Studio 2010 and write your code in C# or Visual Basic. You experience all the benefits of compile-time type checking and IntelliSense as you call methods in the .NET Framework and the client object model. You can also create service references that make it much easier to program against web services, such as ListData.svc.

The experience programming JavaScript in Visual Studio 2010 is nothing like the experience programming a Silverlight application. There is no compile-time type checking, nor is there any IntelliSense when you program against the client object model. Furthermore, you need advanced programming skills with JavaScript and ASP.NET AJAX to call out to a web service, such as ListData.svc, or to perform the required thread switching from a callback method before updating something in the UI. If you are just beginning to learn to write client-side code, developing with Silverlight will be a much better option than writing code by using JavaScript.

Conclusion

This article discussed key design decisions in SharePoint 2010 development. You learned why and when it makes sense to target the sandbox, and also when it makes sense to create SharePoint solutions that require farm-level deployment. You also learned about the issues to consider when deciding to use Web Parts, site pages, and applications to build a custom UI.

This article also discussed different scenarios for using the server-side object model and client object model. You can see that it really comes down to the specifics of a particular scenario and whether the scenario calls for client-side code. You also learned that server-side code and client-side code each have certain advantages over the other when it comes to programming against SharePoint objects and querying lists. One thing that is clear is that SharePoint developers are now writing much more client-side code than they have in the past.

Additional Resources

For more information, see the following resources:

About the Author

MVP ContributorTed Pattison is an author, instructor, and co-founder of Critical Path Training, a company dedicated to education on SharePoint technologies. As a Microsoft SharePoint Most Valuable Professional (MVP), Ted frequently works with the Microsoft Developer Platform Evangelism group to research and author SharePoint training material for developers early in the product life cycle while in its alpha and beta stages. Ted is also co-author of Inside Microsoft SharePoint 2010.