SharePoint 2007 – 10 Best Practices For Building SharePoint Solutions

E. Wilansky, T. Stojecki, P. Olszewski and S. Kowalewski

Code download available from the MSDN Code Gallery
Browse the Code Online

This article discusses:

  • Taking advantage of built-in SharePoint capabilities
  • Deploying SharePoint solutions
  • Creating testable code
  • Branding SharePoint for scale and maintenance

This article uses the following technologies:
WSS, Visual Studio Extensions for SharePoint3

1. Know When to Cross the Divide
2. Take Advantage of Native SharePoint Capabilities
3. Know Critical SPDev Tasks and Information Sources
4. Develop Solutions Off-Server
5. Testing Code and Managing Dependencies
6. Continuous Integration and Automated Build
7. Have SharePoint Manage Custom Config Settings
8. Know Where Configuration Settings Belong
9. Brand SharePoint for Scale and Maintenance
10. Build Deployable Solutions
Enough Said
Additional Tips
Use Relative Links Whenever Possible
Creating Custom Master Pages
Dealing with InfoPath Projects in an Automated Build

The challenges facing developers who work with Windows SharePoint Services 3.0 (WSS) and Microsoft Office SharePoint Server 2007 (MOSS) are as deep and wide as the SharePoint platform itself. If you’re new to this platform, the practices we explore in this article will lead you in the right direction. If you’re an experienced SharePoint developer, these tips should help reinforce your knowledge, encourage discussion, and ultimately lead to building great SharePoint applications. In addition, we’ve provided a number of online references where you can learn more about the topics we discuss.

1. Know When to Cross the Divide

An issue that arises early in a SharePoint development project is how best to interact with other systems. Because SharePoint is a composite application platform, this question is one you will likely have to answer often. Viewing the SharePoint architecture from the Web application level is the easiest way to go about it. An instance of SharePoint contains multiple Web applications. If you are not familiar with SharePoint application architecture, you should review "Architectural Overview of Office SharePoint Server 2007."

Figure 1 shows typical approaches for interacting with SharePoint within a Web application, between Web applications, and with external systems. We’ll cover each of these interactions in the rest of this section.

fig01.gif

Figure 1 SharePoint System Interaction Model

Use the SharePoint object model when you are writing Web Parts, ASP.NET form codebehind, or Web controls that run in the context of a specific Web application (see Figure 1). The SharePoint object model provides a rich set of classes through which to interact with SharePoint. The Windows SharePoint Services 3.0 and Microsoft Office SharePoint Server SDKs provide good coverage of these classes.

Context is an important consideration when handling SharePoint Web (SPWeb) or site (SPSite) disposal. For important information about when you need to explicitly dispose of these objects by using the Dispose method or a using statement, see "Getting References to Sites, Web Applications, and other Key Objects" and "Best Practices: Using Disposable Windows SharePoint Services Objects."

From the perspective of the SharePoint object model, a SharePoint Web application is an important security boundary. Typically, you should not use the SharePoint object model for interactions between SharePoint Web applications. See "Security Programming in SharePoint 2007" for information about other important SharePoint security topics.

When making calls between SharePoint Web applications and between SharePoint and external applications, such as an Office client application, use the SharePoint Web service integration layer. This is a good approach when attempting off-server development tasks in Visual Studio. See the "Develop Solutions Off-Server" section for details.

To interact with other systems, making calls to external Web services is the most common approach, but it is not always the best approach. Some alternatives might be easier to implement, and they might also have the benefit of being significantly faster—for example, making calls to LDAP stores via the Microsoft directory services programming framework or making calls to Project Server via ADO.NET to the Project Server Reporting database rather than via the Project Server Interface (PSI) Web services layer. When the data source is a Web service or database, consider using the Business Data Catalog (BDC). For more information, see the next section in this article, "Take Advantage of Native SharePoint Capabilities."

Microsoft is very clear in its documentation that you should not make calls directly to the SharePoint content and configuration databases. Even so, some applications are using this approach. Whether performance is the argument for this access technique or simply a lack of knowledge about the SharePoint framework, there are safer approaches.

The bottom line is that Microsoft can change the underlying schema in these databases, and there can be more than one content data­base per Web application. Therefore, seemingly benign direct query operations can lead to brittle solutions. Instead, take advantage of the other approaches outlined in this article or develop a different strategy that avoids suboptimal solutions that compromise the integrity of your SharePoint implementations.

2. Take Advantage of Native SharePoint Capabilities

Two situations can lead development teams away from taking full advantage of the native capabilities in SharePoint. First, because SharePoint is such an expansive platform, you might find it easier to build custom solutions rather than spend time to understand what SharePoint provides without custom coding. Second, business owners tend to create detailed requirements, wireframes, and application behaviors that leave you with little flexibility when it comes to using out-of-the-box (OOB) capabilities.

But embracing what the SharePoint platform provides often pays dividends, even if the resulting deliverable deviates slightly from the original requirements. The keys to gaining this advantage are for the development team to thoroughly understand the technology and, more importantly, to clearly communicate the value and tradeoffs of a particular implementation to the business owner.

Acquiring a solid understanding of the strengths and weaknesses of SharePoint is easier said than done. Both WSS and MOSS include SDKs that contain technical documentation, walkthroughs, code samples, and best practices for programming solutions in SharePoint. Also, when information is hard to find, you can use .NET Reflector to look inside some of the core SharePoint assemblies. Figure 2 shows the members of the PeopleQueryControl class in the Microsoft.SharePoint assembly, including the IssueQuery method. The PeopleEditor control (aka People Picker) delegates responsibility for querying SharePoint’s identity store to PeopleQueryControl and lets you override the IssueQuery method to modify the default implementation. As you can see in the figure, .NET Reflector gives you an inside look into how the components interact.

Figure 2 NET Reflector Showing the IssueQuery Method of the PeopleQueryControl

Equipped with knowledge about the capabilities of the platform, you need to articulate the benefits of a particular implementation to the stakeholders in a way that underscores the value of their investment in the technology. It’s especially important with a platform the size of SharePoint not to get hung up early about implementation details but to help the client learn what is possible by releasing early and iterating often. Be sure that your client is familiar with the features of the product by putting in place an effective feedback mechanism that keeps them engaged throughout the entire software development life cycle (SDLC).

Imagine a discussion about displaying a large selection list of entities to a user. You can implement this capability in many ways, such as with the ASP.NET DropDownList control, the GridView control, a custom control, or a third-party control. SharePoint itself also provides a large list-selection control in the PeopleEditor or its base class, the EntityEditorWithPicker control, that you can use for this purpose. These Web controls come with many hooks for injecting your own custom logic, and by using them you take advantage of a rich and intuitive user interface and create a consistent user experience in SharePoint. See "Customizing EntityEditorWithPicker" for an example of how to override methods of the PeopleEditor Web control.

Presenting line-of-business (LOB) data inside SharePoint is another common request. Typically, you start by identifying the gold-source of the data and determining how best to pull that data into SharePoint. Creating Web service proxies or establishing ADO.NET connections to databases is old-hat for many developers. However, the BDC is possibly a better alternative. This SharePoint facility enables you to read data from external data sources and present it inside SharePoint. The BDC supports a wide variety of authentication mechanisms, allows you to create associations between data entities, and is tightly tied to the SharePoint search and list infrastructures.

In addition, SharePoint includes a suite of Web Parts for presenting LOB data through the BDC. And while the BDC doesn’t currently support create, update, and delete operations directly, you can create custom applications to perform these operations and associate them with the BDC through the BDC actions interface. For more information, see the Business Data Catalog topics in the "Resources" sidebar.

3. Know Critical SPDev Tasks and Information

The purpose of this section is to elucidate common tasks that every SharePoint developer might need to complete during software development. This is not a tool review, nor is it intended to promote one tool over another. Instead, we provide suggestions for tools that you can use to complete common SharePoint development tasks.

Building SharePoint solutions is an approach you’ll want to take. Ted Pattison sums it up nicely in his Office Space column "Solution Deployment with SharePoint 2007" when he writes, "Packaging up and deploying your WSS development efforts using solution packages is a best practice, and knowing how to do this should be considered an essential skill." There are numerous ways to package your SharePoint solutions, from manual creation of manifest.xml and diamond directive files (DDFs), to Visual Studio projects that use the Windows SharePoint Services 3.0 Tools: Visual Studio 2005/2008 Extensions (VSeWSS).

Using VSeWSS projects is significantly easier than manually creating DDFs. However, some alternatives are particularly useful for commercial or enterprise deployments, including WSPBuilder, STSDev, SPDeploy, and DDFGenerator. Evaluate the various tools to find one that best fits your needs. The key is to create Solution packages for deployment rather than deploying code components manually.

Debugging client-side behavior can be tricky, and tools such as the Internet Explorer Developer Toolbar (Developer Tools in Internet Explorer 8) make that effort significantly easier. Internet Explorer Developer Toolbar is similar to Firefox add-ons such as FireBug. Another tool that runs in Internet Explorer is the Web Development Helper. Both of these tools are useful for debugging client-side JavaScript, inspecting styles, and walking the DOM. If you need to inspect interaction with IIS, the IIS 6.0 Resource Kit contains a plethora of useful tools. For example, WFetch provides a handy facility for inspecting page output information, such as the output of a custom HTTP handler or authentication header information to verify what authentication protocol you’re using, as shown in Figure 3.

Figure 3 WFetch Showing an NTLM Authentication Header

Troubleshooting server-side code issues can be particularly difficult in SharePoint because errors are obscured behind moderately friendly (though not very helpful) Web pages or in logs following Web service calls. The most important takeaways here are to know where SharePoint logs data and when to make use of a debugger and to be familiar with tools that can help you troubleshoot your SharePoint applications.

One place to start when trying to determine what is causing an application problem is the Windows event logs. In some cases, you can use options for increasing event logging. For example, if you are working with an application that relies on Kerberos authentication, you can increase Kerberos logging to the System event log. There are numerous excellent online resources explaining Kerberos authentication. For concise information on verbose Kerberos logging in Windows Server 2003, take a look at "Kerberos Protocol Registry Entries and KDC Configuration Keys in Windows Server 2003."

The SharePoint and IIS logs are critical to troubleshooting SharePoint application errors. Here’s some brief information about these two critical logging sources:

  • The SharePoint logs are located at <%CommonProgramFiles%>\Microsoft Shared\Web Server Extensions\12\LOGS. You can simplify reading these logs by installing the Log Viewer feature.
  • The IIS logs are typically located at <%SystemRoot%>\System32\LogFiles. Look in the properties of IIS to verify the root location of the logs. Since each IIS Web application has a unique ID, you just match the IIS application ID for the SharePoint Web application listed in IIS with the folder name under the LogFiles directory.

For custom application logging, consider Enterprise Library integration. By incorporating the Enterprise Library Logging and Exception Handling Application Blocks in your code, your logging target, typically a database, can contain logging information and exception detail critical to troubleshooting your custom apps.

The most useful tool for debugging custom application problems is the Visual Studio debugger. If you have Visual Studio installed on your SharePoint server, you have F5 debugging capability. Ideally, you should not have Visual Studio installed on production or model office systems. In addition, you can develop software on local workstations and debug solutions remotely. Remote debugging is fully supported in SharePoint by connecting to the w3wp process hosting your custom application in IIS.

To determine which instance of w3wp is running your application, open a command prompt and run IISApp.vbs on your Windows server to identify the process ID (PID) running your SharePoint Web application. Then, in Visual Studio, select the instance of w3wp with the matching PID.

Another very helpful tool is Exception Display. When you enable this tool on your farm, it replaces the friendly SharePoint error page message with a number of exception display types. For details on how to install and use this tool, click "Exception Display" at the link listed above.

If a deployed Web Part is causing a page load failure, you can open the Web Part maintenance page by appending ?content=1 to the end of the page URL. On the maintenance page, you can close or delete the offending Web Part from the page.

Finally, you can enable application-level tracing in the web.config file of your Web application. See the discussion in "Enabling Application-Level Tracing."

Keep extending the framework. SharePoint is more than capable of integrating custom solutions in a variety of ways. Because SharePoint is built on top of ASP.NET, it inherits the extensibility points of this platform. With the release of WSS 3.0/MOSS SP1, Microsoft now supports the ASP.NET AJAX framework, which means you can take advantage of the ASP.NET AJAX Extensions and the AJAX Control Toolkit. You can ease the installation and configuration procedure by using the Ajaxify MOSS custom stsadm extensions that programmatically add or remove AJAX-related web.config entries by using the SPWebConfigModification class.

With the framework in place, you can use the AJAX control suite and improve the responsiveness of your pages by implementing client-side callbacks. This is particularly important when making external Web service calls in custom Web Parts. See "Client-Side Web Service Calls with AJAX Extensions."

jQuery is another client-side framework that is getting a lot of attention, especially with the recent announcement by Microsoft that it will be supported in Visual Studio. Since the jQuery core library is contained in a single .js file, integrating it into SharePoint is simple. See "jQuery Script Manager" for an approach to embedding jQuery scripts into an ASP.NET Web page.

If you’re looking for information about Silverlight integration, see "Light Up SharePoint with Silverlight 2 Web Parts." The authors explore an example of integrating a Silverlight application with SharePoint.

4. Develop Solutions Off-Server

Whenever possible, you should build your solutions free of the dependencies that SharePoint development often imposes. By using the Visual Studio development server, ASP.NET Web Part framework support, SharePoint Web services, and third-party tools, you can complete most of your development on a standard workstation rather than on a computer running SharePoint.

Because SharePoint runs on top of IIS and ASP.NET, the Web development server included with Visual Studio is an excellent starting point for much of your SharePoint development. For example, you can develop Web Parts, HTTP handlers, and Web controls in this, relatively speaking, lightweight environment.

Some initial work is involved in setting up the environment to host your components. For example, to effectively develop an ASP.NET Web Part, you should create a class project to host your Web Part, a Visual Studio Web Application project, and optionally a unit test project. We have included an example of this setup in the Visual Studio SPTips solution (included with the article’s sample code) that you can use for off-server Web Part development.

In the Web Part project, the default constructor contains a line that sets the ExportMode property of the Web Part:

Copy Code

public WebPartOffServerExample()
{
    this.ExportMode = WebPartExportMode.All;
}

This line allows you to generate a .webpart deployment file based on the properties you configure for the Web part, as shown in Figure 4.

Figure 4 The Web Part Export Menu Option

You can then import the Web Part into SharePoint via this deployment file (Figure 5). You should not use the SharePoint 2003 backward-compatible import file type, .dwp. The underlying XML schema for a .dwp isn’t as rich and requires that you reference the Microsoft.SharePoint assembly early in the SDLC.

Figure 5 The Web Part Imported into Share-Point

Note that you can ensure the creation of .webpart deployment files by inheriting from the WebPart class in the System.Web.UI.WebControls.WebParts namespace rather than the Microsoft.SharePoint.WebPartPages namespace. (For examples of when you might want to inherit from SharePoint’s WebPart class, see the source listed in the "Resources" sidebar.)

Microsoft exposes a significant subset of the SharePoint object model through Web services. Using SharePoint Web services to access the object model allows you to develop a solution without a dependency on direct access to SharePoint assemblies. SharePoint hosts the Web services in the _vti_bin virtual directory on each Web Front End (WFE) server.

In Visual Studio, you add SharePoint Web services to a solution in the same manner as you do any Web service reference. SharePoint Web service URLs have the following format:

Copy Code

http://<SharePointServer>:port/[sites/][SubSite/]_vti_bin/WebService.asmx

where <SharePointServer> is the URL associated with the Web application. For example:

Copy Code

http://www.contoso.com:35000/_vti_bin/Lists.asmx

When you add a Web service reference, Visual Studio creates proxy classes for both the service and the data types used by the service. For more information on interacting with these Web services, please see "WSS SDK 3.0 Topic: Web Service Guidelines" and "SharePoint Web Services."

Implementing a three-tiered architecture furthers the goal of isolating code and removing dependencies on SharePoint and other outside sources. This approach can improve your ability to develop off server by abstracting business, data access, and UI logic from one another, enabling you to break code into manageable pieces and reduce dependencies between them. This approach also yields more testable code; more on this in the section "Testing Code and Managing Dependencies".

There are other tools you can use. Removing the dependency on SharePoint across the entire codebase is unrealistic. Developing for SharePoint off server generally requires the use of a SharePoint instance, usually hosted in a virtual machine, early in the SDLC. With the growth of SharePoint development, several tools have been created to deal with this significant dependency. One such tool is Bamboo Solutions’ SharePoint on Vista Installation Helper. This tool enables the installation of WSS 3.0 SP1 or MOSS 2007 SP1 on Windows Vista, giving you the ability to develop SharePoint-dependent solutions without needing Windows Server.

Microsoft does not support running SharePoint in this way. However, this approach has resonated in the SharePoint development community because it helps reduce the footprint that this dependency on SharePoint creates. For further information, see "How to install Windows SharePoint Services 3.0 SP1 on Vista x64/x86."

5. Testing Code and Managing Dependencies

The widespread adoption of unit test frameworks and related test tools has naturally made its way into SharePoint development. Unit tests and integration tests are two primary test categories. Both test types exhibit different characteristics and require the use of different tools and techniques.

When writing unit or off-server tests, it’s considered a best practice to simulate external dependencies with substitutes such as stubs or mocks. By passing in objects that mimic external dependencies, your test becomes faster and more focused on the behavior you are testing. To be effective, this approach requires that you follow the principles of testable, object-oriented design, or use a specialized framework for isolating tightly coupled components of your solution.

Identify the behaviors and business rules that are infrastructure independent and make sure you have a strategy for testing them in isolation. To isolate interactions with SharePoint, a database, or a Web service, you can introduce the Repository pattern to abstract away the details of the back-end system. These repository objects can be passed into higher level components by using inversion of control (IoC) and dependency injection (DI) principles. For information on IoC and DI, see "Tame Your Software Dependencies for More Flexible Apps."

To increase the testability of your presentation components implement the Model-View-Presenter (MVP) pattern. For more information about testable code patterns, see "Design for Testability."

Other major challenges that SharePoint developers face when unit testing deal with the SharePoint object model. Simply put, testing those components in isolation is a nontrivial task. It is a direct result of a limited number of interfaces and abstractions as well as a high number of sealed classes—classes with inner dependencies or without a public constructor.

One product equipped to deal with these shortcomings is TypeMock Isolator, a commercial mocking framework that allows for mocking of sealed, concrete, static, or internally constructed classes. For other mocking frameworks to be applicable, you need to adhere to patterns and principles we have already eluded to. TypeMock Isolator or its new SharePoint-specific version, Isolator for SharePoint, will work around these limitations and allow for increased code coverage without relying on a running instance of SharePoint. The patterns and practices (P&P) team also uses TypeMock Isolator in their SharePoint Guidance reference architecture.

At some point, you will have to write integration tests that are dependent on the SharePoint object model. It is good practice to manage your unit tests that are sever-independent from those that are server-dependent.

You can use the Test List Editor in the Test Manager in Visual Studio to separate your unit and integration tests. For instance, you could create two lists of tests: server dependent and server independent (see Figure 6). This approach allows you to select which set of tests to run, depending on whether or not you’re on the server.

Figure 6 The Test List Editor Showing a Categorized Test List

In cases in which Visual Studio is installed on the server, you can run and debug your tests in the IDE or use the MSTest.exe command-line tool to run server dependent tests. Unfortunately, MSTest does not run unless Visual Studio is installed on the server. Our hope is that a future version of MSTest will not include this heavy dependency.

MSTest.exe allows you to specify which tests you want to run through command-line arguments. When you run MSTest.exe, you must specify either the /testcontainer or the /testmetadata option. By using the /testmetadata option, you can specify which tests will run. For example, to run all server-dependent tests, type:

Copy Code

MSTest /testmetadata:SPTips.vsmdi /testlist:ServerDependentTests

To run a specific test within the server-dependent tests, type:

Copy Code

MSTest /testmetadata:SPTips.vsmdi /test:GetTasks_ShouldReturnTasks

For examples of on-server tests and tests using a mocking framework, see the sample code in the Visual Studio SPTips solution included with this article’s code download.

6. Continuous Integration and Automated Build

Keeping code in source control, relying on continuous integration, and automating the build process are essential steps to efficient release of high-quality code assets. SharePoint makes the setup of this environment challenging, to say the least. For this tip, the most important starting point is the "Team Development Overview" topic.

Later in the overview, you’ll see the SharePoint Guidance topic "How to: Create an Automated Build and Deployment Solution with Team Foundation Server Build." This topic focuses on creating build targets to build and deploy solutions. While this method has merit, it is not useable when the TFS build and SharePoint servers do not reside in the same environment, as is often the case in the enterprise. Building your solution packages using targets limits the use of packages to the automated build environment and thus does not encourage early development and testing of packages by developers.

The alternative is to use post-build events within Visual Studio. The post-build events can be set up to perform the same packaging steps as the MSBuild targets and allow developers to build packages for deployment to their own sandbox environments. This approach also works with third-party tools such as WSPBuilder and STSDEV.

When deploying to the enterprise, you might also need to consider versioning solution packages. Tying the solution version to the current build version is one approach. This can be facilitated by using custom application code run in the AfterBuild MSBuild event or from the post-build event. Also consider solution IDs in the automated build and whether to generate new IDs with each build. This decision will impact your ability to upgrade solutions in the future. As a general rule, generate new solution IDs when assembly versions change. Otherwise, keep the solution IDs the same where version IDs are static between builds.

Rather than repeat information that you can get from the SharePoint Server Developer Center, we will augment this tip by focusing on how to further simplify the automated build process. In the SharePoint guidance topic "How to: Create an Automated Build and Deployment Solution with Team Foundation Server Team Build," the P&P team assumes you are using VSeWSS/extensions.

While VSeWSS is a fantastic addition to a SharePoint developer’s toolkit, with capabilities like the WSPView panel that allows you to configure your solution on the fly, we’ve found that it is not well suited for medium to large implementations or teams that follow agile development methodologies.

The P&P SharePoint guidance team documentation states that VSeWSS provides one-click deployment and F5 debugging. The one-click deployment capability is certainly part of VSeWSS, but the F5 debugging capability has more to do with the fact that you must run Visual Studio local to your instance of SharePoint. This is a requirement for installing VSeWSS. Although you can use a registry hack for getting VSeWSS installed on a workstation, most of the extension’s benefit is lost when installed on a workstation.

The documentation also states that many tools such as WSPBuilder and STSDEV require developers to maintain Feature.xml and Manifest.xml files for SharePoint solution packaging in a Web solution package. In reality, these tools are constantly evolving. For example, WSPBuilder now includes extensions that allow easy maintenance of Feature.xml and Manifest.xml in Visual Studio 2005 and 2008.

VSeWSS is most useful when you are unsure about how to structure a SharePoint project. For example, you might want to use a VSeWSS project type to determine the structure of a Web Part or a SharePoint Workflow project. Once you know how, you can take that information and move it to a ubiquitous project type. The primary issues around using VSeWSS for a medium to large project are as follows:

  • The extensions are designed to be installed on an instance of Visual Studio running on a SharePoint server. Therefore, they have a hard dependency on WSS.
  • Developers who have not installed VSeWSS will not have the special project types that VSeWSS creates and will not be able to open projects that rely on them.
  • Rebuilding a solution is made more complicated by VSeWSS.

The guidance documentation suggests that the other approach is to manually create a SharePoint solution file for each Visual Studio solution, along with the deployment manifest manifest.xml. However, tools such as WSPBuilder allow you to automate this step within your build.

The keys to a successful automated build are:

  • Use standard Visual Studio project types (i.e., class projects for Web Parts) so that all developers can easily open a project.
  • Structure your code project so that solution packaging is integrated into the project, as shown in Figure 7. There is no need to create a separate deployment project.
  • Set up a post-build event to run WSPBuilder or another automated solution building tool to build the Sharepoint solution file. This approach works both for local deployment of the solution and for the automated build process.
  • Use Macro conditions to control the parts of your post-build event that get called depending on where the build is occurring.
  • An automated build is further complicated by an InfoPath project. For information on this, see the tip "Dealing with InfoPath Projects in an Automated Build" in the online version of this article.

Figure 7 Solution Packaging Structure Integrated into the Web Part Project Code Download

Don’t deploy to the global assembly cache (GAC) until you move to an integration environment. Keeping assemblies in the BIN folder makes debugging custom SharePoint applications significantly easier. There are certain project types that don’t fit this model, such as SharePoint event handlers and SharePoint Features. By placing compatible assemblies in the BIN folder, developers in a shared development environment won’t have to endure frequent IIS resets after each deployment.

Some pointers for running SharePoint assemblies from the BIN are:

  • Decorate your assembly with the [assembly:System.Security.AllowPartiallyTrustedCallers] attribute.
  • Configure custom code access security (CAS) policy or set web.config to full trust, as shown here:

Copy Code

<system.web>
  <trust level="Full" />
</system.web>

(Note that setting the trust level to full is only appropriate for local or internal development where your code assets will eventually be deployed to the GAC.)

  • Sign your assemblies for eventual deployment to the GAC.

7. Have SharePoint Manage Custom Config Settings

Like any application, SharePoint solutions rely on configuration settings to operate properly. A custom application with only a few configuration settings may be easy to manage manually. In contrast, when developing enterprise or commercial applications in SharePoint, the number of configuration settings can be considerable.

As a result, knowing the different setting types and how to manage them is important to developing, deploying, and managing applications. The best approach is to increase the number of settings that SharePoint manages and reduce the number of settings managed manually.

Understanding the types of settings helps identify where the settings belong. SharePoint configuration settings generally fall into three categories: core, custom, and SharePoint settings.

Core settings are used across a SharePoint Web application. Enterprise Library application blocks and external Web services configurations are examples of typical core settings.

Custom settings are for custom build components. These settings are used to provide configuration settings for the custom component and are not shared outside the component. For example, custom settings could be used to provide directory server settings for an LDAP lookup.

SharePoint settings are required to make the solution work within SharePoint. Settings in this category include SafeControls entries, SessionState customizations, or registering HttpModules.

After you categorize your settings, you can deploy them to the right locations to manage them. The goal is to reduce the number of settings managed manually. Letting SharePoint handle settings reduces the number of errors that can occur when applications are deployed.

Core settings are best managed in source control. This allows for maintaining a settings history while providing a single source of truth for the settings. In addition, this approach allows for maintaining discrete versions of configuration files for development, test, and production environments.

You can automate custom settings installation and management by using the SharePoint object model and deployment tools. Use the SPWebConfigModification class, solution deployment, and the CONFIG directory under the SharePoint 12 hive to form your configuration management strategy. Please see the "Build Deployable Solutions" section in this article for additional details about deploying through solutions.

The SharePoint SPWebConfigModification class allows you to programmatically register settings in the web.config of a SharePoint Web application. Using SPWebConfigModification, you can write a console application or stsadm extension to list, add, or delete configuration entries. This approach allows for rapid and consistent modification of large sets of SharePoint configuration settings. The SPWebConfigModificationType enumeration within this class contains three values specifying the type of modification being made: EnsureChildNode, EnsureAttribute, and EnsureSection. Exercise caution when using EnsureSection because entries added with this enumeration cannot be easily removed. For more information, see "Automate Web App Deployment with the SharePoint API."

The SharePoint CONFIG directory allows you to declaratively register settings by maintaining XML files in this directory. WSS applies settings in the XML files to the web.config when SharePoint creates a Web application. Settings in this folder are applied to all Web applications. For information on this approach, see "Managing Web.Config Customizations."

8. Know Where Configuration Settings Belong

The previous tip explored different types of SharePoint configuration settings and how to manage them. As an application is promoted through environments, such as from test to production, changes to the configuration settings, especially those pointing to external systems, can feel like sand shifting under your feet. Knowing where configuration settings belong can put management of environmental settings on more solid ground.

Composite application development has increased reliance on configuration settings. The power and ease of use of configuration settings has arguably led to their overuse. One way to reduce constant changes to these settings is by applying the convention-over-configuration paradigm by instead inferring values from things such as naming conventions. We outline an example of the convention-over-configuration paradigm in the "Continuous Integration and Automated Build" section by demonstrating how to integrate SharePoint Solution packaging into your Visual Studio projects. A related example of this paradigm appears in the Web content tip, "Use Relative Links Whenever Possible."

Instance-specific settings are unique to each instance of a Web Part. For example, you might have a Web Part that displays a list of projects on a program manager’s page, while on a developer’s page it shows project and task details. Instance-specific settings are best stored in a custom Tool Part or in a Web Part’s miscellaneous Tool Part properties.

Configuration settings being used by more than one component are considered global settings. Examples of settings in this category are URLs for external Web services, business object settings, and data settings. These settings are best kept in web.config and managed as described in the "Have SharePoint Manage Custom Config Settings" section.

9. Brand SharePoint for Scale and Maintenance

Branding your SharePoint site provides users with the most obvious visual indication of your application’s purpose. Branding involves working with various artifacts, such as Master Pages, content pages, page layouts, site definitions, and CSS. For a tip on creating custom Master Pages, see the online tip "Creating Custom Master Pages."

Resources

Microsoft Office SharePoint Server 2007 and Windows SharePoint Services v3

Business Data Catalog

SharePoint 2007: BDC—The Business Data Catalog

WebPart Class (Microsoft.SharePoint.WebPartPages)

Make sure your application scaling and maintenance strategy takes into account how you will manage these branding artifacts. For details on SharePoint branding, see "Microsoft Office SharePoint Server 2007 and Windows SharePoint Server v3" in the "Resources" sidebar.

Before choosing a tool for branding, consider the size of your SharePoint implementation, the extent of your branding effort, and the expertise of the developers supporting the application. We will focus on two tools: SharePoint Designer and Visual Studio.

SharePoint Designer has its roots in FrontPage and is a Web design tool useful for editing Master Pages and CSS. However, the ease of use provided by SharePoint Designer comes at a price:

  • There’s no integrated source control support.
  • Changes made within SharePoint Designer result in the modified content becoming unghosted.

In an unghosted state, copies of the content are stored in the content database instead of the file system. As a result, unghosting has the following effects:

  • Makes deployments difficult to manage because the content can be updated only within SharePoint or SharePoint Designer
  • Disconnects a site from updated content deployed to the file system
  • Leads to potential performance issues on large, active SharePoint implementations

For these reasons, we believe SharePoint Designer is most appropriate for small to medium implementations and prototypes.

Visual Studio provides a consistent development environment for both application components and branding artifacts, but it lacks the graphical editing functionality found in SharePoint Designer. Because of this, developers must be more proficient with editing HTML and CSS. A good project structure must be set up to maintain the branding artifacts. With Visual Studio’s integrated source control support, it’s easier to manage environment-specific configurations and package branding artifacts to be deployed across multiple environments. In addition, branding artifacts remain ghosted. Therefore, Visual Studio is our preferred SharePoint branding tool for large enterprise and commercial implementations.

There are three approaches to applying branding: site templates, custom site definitions, and OOB site definitions coupled with customizations via Feature Stapling. Creating custom site templates may be the fastest approach for small implementations and prototypes. However, sites created from a template will not update when a new template is uploaded. Custom templates do not allow you to specify the template ID, which will require changes to any provisioning code that references the templates. Also, site templates create only unghosted content, which could impact performance.

Site definitions are more flexible and portable than site templates. You can manage the site definition file (onet.xml) and associated content in source control and deploy ghosted content, allowing a site to be updated with new content provided that it has not already been customized. Site definitions can be difficult to create because of the complexity of the XML you need to edit. This task is made easier by using OOB site definitions (found in 12\Template\SiteTemplates) as a starting point or by exporting a site definition using VSeWSS. For information about site definitions, see "Site Definitions Demystified."

When dealing with medium to large implementations, combining OOB site definitions with custom Features is the best approach. Features can be used to extend site definitions and provide a modular approach to provisioning sites. For a good overview of Features, look at the Office Space column "Features for SharePoint." The VSeWSS extensions, as well as some third-party tools, provide templates for creating common Features used in branding Web sites.

Feature stapling lets you attach a Feature to a site definition and have it enabled when a new Web site is created. This is a great way to apply your branding to the SharePoint OOB site definitions.

10. Build Deployable Solutions

You can get your components into a SharePoint Web application in several ways. This section focuses on how to utilize the packaging and deployment frameworks that SharePoint provides, including Web solution packages (Solutions/WSPs), Features, and the SharePoint object model.

Deciding how to package components depends largely on where the components are being deployed. Solutions contain files that will be deployed to the server. Features contain content that will be deployed to the content database.

A Sharepoint solution contains the assemblies and resources to be deployed to SharePoint Web applications. Solutions are compact, simple to deploy and retract, and SharePoint handles mirroring file updates in Sharepoint solutions across multiple servers in a farm. You can also use Sharepoint solutions for web.config modifications. See the sections "Know Critical SPDev Tasks and Information Sources" and "Have SharePoint Manage Custom Config Settings" for additional details on solutions and web.config modifications. Figure 8 lists the common folder locations supported by solutions and their contents. The "12 hive" refers to the SharePoint application root, or <%CommonProgramFiles%>\Microsoft Shared\Web server extensions\12 by default.

Figure 8 Common File Locations Accessible from WSPs

Folder in 12 hive

Contains

\ISAPI\HELP\[LCID]

SharePoint help files. Deploy your own .chm files to this folder (or a localized subfolder)

\CONFIG

Web.config customizations

\ISAPI

SharePoint web services (deploy your custom web services here as well); maps to /_vti_bin

\Resources

Global .resx files accessed from custom features and site definitions

\TEMPLATE\CONTROLTEMPLATES

.Ascx user controls; maps to /_controltemplates

\TEMPLATE\FEATURES

Features, of course!

\TEMPLATE\LAYOUTS

Common site pages; maps to /_layouts

\TEMPLATE\IMAGES

Common site image files; maps to /_layouts/images

\TEMPLATE\SiteTemplates

All SharePoint site definitions; create a <subfolder>\xml to deploy your onet.xml custom site definition

\TEMPLATE\THEMES

All UI elements used in themes; clone an existing theme folder to create your own

\TEMPLATE\[LCID]\XML

Webtemp.xml files to define available site definitions; add an xml file here for your custom site definition

\TEMPLATE\ADMIN

Pages used by Central Admin; maps to /_admin

\ADMISAPI

Administration web services; maps to /_vti_adm

The following are important rules to remember when working with solutions:

  • Because SharePoint solutions are managed in the configuration database, there can be only one unique instance of a SharePoint solution in a farm. This point is important if you intend to use the same farm to host different releases of the same Web application—for example, both current maintenance and future development environments.
  • SharePoint tracks Solutions by ID not by name, so you need to maintain solution IDs in source control if you intend to upgrade Solutions in the future.
  • The 12 hive is a shared Web application space. If you plan on hosting multiple Web apps in the same farm, you need to ensure that your SharePoint solutions do not overwrite existing SharePoint files or files deployed by other solutions in this space.
  • Solutions cannot deploy files outside the folders listed in Figure 8, including folders under the Web application, such as wpresources, global _wpresources, or other folders outside the 12 hive.
  • Solutions cannot deploy content inside a SharePoint Web application. This is the role of SharePoint Features.

Features can make Web Parts available in the gallery, upload and publish files to document libraries, and perform custom actions such as setting the site theme or default Master Page by using Feature receiver assemblies. See the information about using the right branding technique earlier in this article for information on using Features for branding.

Here are some caveats for creating Features:

  • Features do not track added content, so it’s the responsibility of the Feature to clean up after itself when it is deactivated by using a Feature receiver. Consider the entire life cycle of the Feature and whether content deployed by the Feature may be needed by other parts of the Web application before the content is deleted. For example, removing a Master Page on deactivation of a Feature will break any pages that inherit from that Master Page.
  • Deactivate a Feature from all Web applications before removing the solution used to deploy the Feature. If you don’t, the solution deployment will fail, and if the Feature folder has been removed, you will need to force an uninstall of the Feature using STSADM.

Enough Said

Using this article as your map, review the references provided for information and download the article’s code sample to help you get started. Perhaps as you develop applications on the SharePoint platform, you will review these best practices again and also find use in the code samples. If you need clarification or want to give us feedback about the tips we’ve provided or other tips you consider important, please send us your questions or comments, and we will endeavor to respond quickly. You can reach us via e-mail at ewilansky@yahoo.com.

Additional Tips

Here are some additional tips for developing SharePoint solutions.

Use Relative Links Whenever Possible

Consider using relative links rather than absolute links. Including relative links to locations such as Document libraries, data connections, and Reports libraries simplifies deployment from one SharePoint instance to another. With the Reports library example in mind, if you use a consistent Web location to the Report library in all your SharePoint environments, you’ll no longer need to change pointers to reports as you move your application from one environment to the next. Typically, convention over configuration applies to code configuration, but this concept can also be loosely applied to other configuration aspects of your deployments.

On a related note, we hope that Microsoft will support relative links inside the SharePoint platform, where currently some configuration settings require absolute links. For example, you must specify an absolute URL to the Form library in an InfoPath .udcx data connection fi le, and the ReportViewer Web Part requires an absolute path to the report definition.

Creating Custom Master Pages

One common way to brand SharePoint sites with your look and feel is to create custom Master Pages, which give you the most control over the layout of your site. You can take an existing SharePoint Master Page and modify it to meet your needs. This approach works best if the existing Master Page is close to the layout you want. If the look and feel you want is very different from any of the OOB Master Pages, you might be inclined to start from scratch. However, because SharePoint requires certain functionality in Master Pages, it’s recommended that you start with a minimal Master Page and build your look and feel from there. To find out more about creating a minimal Master Page, see “How to: Create a Minimal Master Page” at . You can also download some minimal Master Pages from Heather Solomon’s blog, which is also listed in the Resources section.

Dealing with InfoPath Projects in an Automated Build

Projects created in Microsoft InfoPath Designer will further challenge your efforts to automate your build. The best you can really do is let InfoPath and SharePoint handle the packaging. See “Automate Web App Deployment with the SharePoint API” in the Resources section for details about how to get portable solution packages from InfoPath projects.

Ethan Wilansky is a director in FTI Consulting’s Technology Practice and focuses on creating custom SharePoint solutions. As a Microsoft Directory Services MVP, he concentrates on the DS programming framework and is also a member of the Office Developer Advisory Council.

Paul Olszewski is an Information Specialist on a .NET Capability team. He specializes in creating and deploying reusable component applications leveraging Microsoft technologies.

Tomek Stojecki works at Annapolis Computing where he specializes in the architecture and development of .NET apps using design patterns and agile methodologies. He has consulted on a number of SharePoint based projects.

Stefan Kowalewski is a senior consultant on a SharePoint development team. He provides technical expertise and brings proven agile experience to custom SharePoint development efforts.