Documente Academic
Documente Profesional
Documente Cultură
Contents
Additional Resources
We start by understanding what SharePoint development actually entails before discussing the different
techniques for building, packaging, deploying, and maintaining Windows SharePoint Services solutions.
Required Development Skills
People often ask what it takes to be a skilled SharePoint developer, and are surprised to discover that the
developer must master many skills.
Following is the list of areas in which to gain expertise that we have identified as being helpful when
starting with SharePoint development.
ASP.NET 2.0
The latest version of Windows SharePoint Services and Microsoft Office SharePoint Server (MOSS) 2007
rely completely on Microsoft ASP.NET 2.0 as the foundation. Therefore, being skilled in ASP.NET 2.0
concepts, terminologies, and development is the top priority for a Windows SharePoint Services
developer. In addition to understanding the flow of an ASP.NET request, its different stages, and its
internal architecture and extensibility options, a developer must be experienced in developing and using
master pages, content pages, ASP.NET server and user controls, templates in ASP.NET, ASP.NET Web Parts
and their infrastructure, and the ASP.NET provider model. (Many resources are available to you if you
need to come up to speed in any of these areas, however, these are beyond the scope of this article.)
When working on Windows SharePoint Services solutions for information workers, you often must build
custom workflows. The built-in workflows that are delivered with MOSS 2007 answer—to a certain
extent—the demands of the business, but developers are often asked to build custom workflows using
the extensions for both Windows Workflow Foundation (WF) and the project templates for building
SharePoint-specific workflows. To succeed, the developer needs a good understanding of WF, including
the process of building the workflow, building custom activities, interacting with the SharePoint
environment within the workflow, and more.
XML Technologies
Windows SharePoint Services technologies rely heavily on XML technologies. These are the foundation for
the many schema definitions that drive the provisioning engine. There are schema definitions for sites,
lists, document libraries, fields, content types, and more. The Collaborative Application Markup Language
(CAML) is used in most of these schema definitions. In addition, developers must also know about the
related XML technologies such as XSLT and XPath because in their development on Windows SharePoint
Services, they will encounter those technologies as well.
A Windows SharePoint Services developer must understand the APIs that are exposed by both Windows
SharePoint Services 3.0 and MOSS 2007. Building solutions with Windows SharePoint Services requires a
deep understanding of many of the classes that are exposed within the object models. In addition, if the
applications target smart clients working remotely with SharePoint technologies, knowledge of the XML
Web services delivered with Windows SharePoint Services and MOSS is also necessary.
Finally, all of the solutions must be deployed and made available within the SharePoint server farm
scoped to a certain level (for example, a site collection). You must understand how to package the
different components that make up a solution, and how to install and activate the features that make the
solutions available on new and existing sites. This article provides more information and guidelines on
how to do this.
Figure 1 displays the different components and the interaction flow of a mainstream ASP.NET application.
Users send requests to the server running Internet Information Services (IIS) for specific resources. These
requests are accepted by IIS and delegated to an ISAPI extension DLL for further processing. Typically,
resources are retrieved from the file system, such as .config files, .aspx pages, cascading style sheets,
custom-built .NET assemblies, and user controls. All of these can act on the final response that is delivered
to the user in his or her browser. In many applications, an interaction with a data store is also needed to
store and retrieve data that is used to process the request and generate the response.
So, what is different when we compare Figure 1 with Figure 2, which represents the components and flow
for a site based on Windows SharePoint Services?
As you can see in Figure 2, Windows SharePoint Services abstracts developers from many of the details of
hosting highly scalable, template-driven sites. In many cases, SharePoint administrators and experienced
users do not even touch that low-level infrastructure. However, an understanding of it is helpful.
Windows SharePoint Services is a site-provisioning engine that relies heavily on schema definitions for
templates of many types of artifacts that are important to its environment. There are definitions for site
templates; for infrastructure pages such as the default.aspx, which make up the home page of a team site;
for lists and libraries; and for helper pages that enable the interaction among the content that is stored in
these different containers.
When starting a request for a Windows SharePoint Services page, there is interaction with the
configuration database and the content database that retrieves the details of the request. This includes
accessing the many XML files that contain the schema definitions, and accessing building blocks (Web
Parts) that each have to execute their code that is encapsulated in a .NET assembly made available via
either the global assembly cache or the local bin folder. The Windows SharePoint Services provisioning
engine joins all these processes.
When we look at the traditional ASP.NET application again, what happens there if you need more than
one application, maybe two, five, or even dozens? Figure 1 starts to look complex because there the same
infrastructure is repeated for each additional application. Developers following the best practices and
patterns can produce many re-usable building blocks, but much of the infrastructure must still be re-
created each time.
Assembly-Based Solutions
We can refer to these solutions as code-based solutions. Assembly-based solutions are developed with
managed code (a .NET Framework language such as Microsoft Visual C# or Microsoft Visual Basic 2005)
and compiled as a .NET assembly (a DLL). You can build different types of these solutions as well. The
following table describes only some of the possible assembly-based solutions.
Web Parts Building blocks for a SharePoint Web Part Page that deliver specific
functionality to the visitor of the site. Web Parts can deliver data from
stores that are not based on Windows SharePoint Services (such as
Microsoft SQL Server and Oracle stores); capture data to drive business
processes; aggregate or roll up information that is available in the
SharePoint sites, or perform many other functions. Many Web Parts are
available by default with both Windows SharePoint Services 3.0 and
MOSS 2007.
Event handlers A .NET assembly containing one or more classes that encapsulate code
that is executed when certain events (such as adding an item to a list,
creating a column for a document library, deleting a site, and so on) occur
in SharePoint sites.
Information A rich policy framework in MOSS that developers can use to build
management custom policies that enforce certain behavior for content stored and
policies managed in SharePoint sites.
Timer Jobs Assemblies containing code that can be scheduled and executed by the
SharePoint Timer Service. An example is a job scheduled to create a
report every evening for the administrator about documents that have
been checked out for more than a week.
ASP.NET Resources
Figure 2 showed the infrastructure that Windows SharePoint Services uses to deliver the sites. This
infrastructure contains many ASP.NET resources that are directly available and help deliver the simplified
development experience you have with Windows SharePoint Services. As a developer, you can create and
integrate your own resources. Table 2 describes the possible types of resources you can create.
Site page An ASP.NET page that is stored in a document library in the site collection
itself (and is thus stored in the content database). Can be used to deliver
custom functionality (such as reporting or dashboard pages) to the user. Site
pages can be dynamically created and offer much flexibility. However,
because they are stored in the content database, Windows SharePoint
Services applies a strict security policy to these pages, and no inline code is
allowed. Additionally, these pages are run in no-compile mode.
Style sheets Together, these define the look and feel of a site, as well as the common
and master functionality that is used by all the pages of a site.
pages
User control ASP.NET user control (.ascx file) that can deliver common functionality to
the pages in SharePoint sites. Windows SharePoint Services provides several
controls in the \12\Template\ControlTemplates folder. Create additional
custom user controls, and for example, visualize them within the master
pages. User controls can deliver a particular editing experience to the user,
such as custom information management policies or custom fields.
Schemas
Schemas are XML-based solutions that use the Collaborative Application Markup Language (CAML). Table
3 describes the features whose delivery you can drive by using schemas.
Custom Lists The schemas for custom lists and document libraries are also defined via
CAML-based files, many times as part of a Feature definition. However,
they can also be part of a custom site definition.
Site Columns Schema for re-usable packaged definitions of content that can be stored and
and Content managed in SharePoint containers (lists and document libraries). Site
Types columns and content types are delivered through Feature definitions most of
the time.
Custom Field These CAML-based files, together with a .NET assembly that contains the
Definitions code-behind, deliver additional field types that users can select from when
creating custom metadata in a document library, for example.
Data Manipulation
All of the content that is stored and managed in SharePoint sites, together with all the configuration data,
is kept in SQL Server databases that you do not need to interact with directly. Windows SharePoint
Services and MOSS have very rich object models that are delivered by a number of .NET assemblies, of
which the Microsoft.SharePoint.dll and the Microsoft.Office.Server.dll are the most important.
The server object model is accessible only when the application is deployed to one of the computers that
is part of the server farm. If the application accessing Windows SharePoint Services is remotely deployed,
use the Web Services APIs instead.
Solutions that directly interact with the SharePoint classes must have access to the SharePoint context of
the sites (either the collaboration sites or the administration sites, depending on the type of the solution).
Examples are Windows–based applications that are deployed to a server running Windows SharePoint
Services, Web Parts that run in the context of Windows SharePoint Services, custom Web services that
expose data in a customized way, Windows services that run on the SharePoint server, and more.
Numerous Web services are available in Windows SharePoint Services that expose most of the necessary
data manipulation operations. However, when in need of custom functionality, you can always create
custom Web services and have Windows SharePoint Services host and integrate them with the built-in
Web services.
There is also an HTTP-based protocol, the FrontPage Server Extensions Remote Procedure Call (RPC)
protocol, which is used by remote clients to manipulate documents that are stored in document libraries
in Windows SharePoint Services. Microsoft Office system clients are examples of smart clients that use this
protocol.
Working Remotely
In the setup we describe, developers are working locally on a non-server operating system with Microsoft
Visual Studio 2005 installed. They build the solutions, and then go through the steps of deploying these
solutions to a central server running Windows SharePoint Services 3.0 and possibly MOSS. Figure 3
displays the setup.
Depending on the type of solution, specific .NET assemblies (for example, the Microsoft.SharePoint.dll)
must be copied to the local development environment.
There are many advantages to working this way. The first important advantage is that developers do not
have to install server software on their local development computers. This impacts licensing, and also
eases the installation burden for developers who are already doing a lot of development on their local
computers. The second advantage is that you can set up a centrally managed source-code control system,
and the backup can also be centrally managed by the administrators.
However, there are many difficulties that developers experience when working this way. First, debugging
the code remotely is challenging. For example, when building a Web Part in which the developer needs to
debug the code, you need to consider many environment variables such as the following:
The developer requires powerful privileges on the server while debugging the solution for a site.
The developer also blocks all of the other developers who are working on solutions for the same
site.
Every time testing must be done, developers must package the code and go through the
deployment steps to the server before being able to see their code in action. This can be good,
because from the start, developers have to take care of the proper packaging, but it is often
going to be counter-productive when working this way.
Note:
Working Locally
Alternatively, you can configure the development environment so that all of the SharePoint development
work can be done locally. Figure 4 shows this setup.
In the long run, the developer’s productivity benefits from being able to build, test, and debug
the solution locally. This typically is the case when building assembly-based solutions.
Testing the solution does not impede the work of colleagues. However, working locally requires
more discipline from the developers. Setting up an efficient back-up and source-control system,
for example, is more challenging in this situation.
The local development environment can either be a native installation of Windows Server 2003
with Windows SharePoint Services 3.0 and possibly MOSS installed. However, as mentioned
previously, this can be quite a burden for the developer who has other development work to do
on the same computer. A configured Microsoft Virtual PC development environment is a good
choice if you do not want to do a native installation, although it does require more memory and
hard-disk space to use this approach.
Individual item templates for adding Web Part classes, custom field controls, and modules to an
existing project, as well as list definitions, and content types (both with an optional event
receiver).
An external Windows application called the SharePoint Solution Generator that can pick up a
provisioned team site, reverse-engineer it, and provide you with all of the individual pieces
assembled together in a Visual Studio 2005 project.
It is important to remember that Visual Studio 2005 Extensions are meant to support the developer in the
development process, and through the testing and debugging phases. As you use the walkthroughs in
this article, the extensions can enable you to focus on the code, start writing it without the requirement of
first setting the project infrastructure, have the code compiled and packaged in a Windows SharePoint
Services solution, and deployed without hassle to one of your site collections—ready to be tested and
debugged.
However, you can use a few configuration options to deviate from the default way the solution is
packaged and deployed. The different scenarios where you will have to take control of, package, and
deploy the solutions in a manual way are described later in this article.
Following are a few walkthroughs that show some of the development tasks you can undertake with the
Visual Studio Extensions for Windows SharePoint Services 3.0.
If you are familiar with the Visual Studio Extensions for Windows SharePoint Services 3.0 and with using it
to build Web Parts, you might want to proceed to the next section. For the readers who are not familiar
with the extensions, this short walkthrough describes the different steps for creating a project with one
Web Part showing the world famous Hello World string. (Don’t worry! It is going to get more exciting.)
To create a project with one Web Part that shows the Hello World string
1. Open Visual Studio 2005, and then create a new Web Part project as shown in Figure 5.
2. Write only the minimal code shown here to output a small string as the body of the Web Part. The
final code looks like the following.
C#
Print
using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
namespace MSDN
{
[Guid("28c3eefe-2c03-4791-9f69-4405c80e1d92")]
public class HelloWorldWebPart :
System.Web.UI.WebControls.WebParts.WebPart
{
protected override void Render(HtmlTextWriter writer)
{
writer.Write("Hello Readers!");
}
}
}
3. Before testing the Web Part, perform the following configuration tasks. As displayed in Figure 6,
open the properties of the project in Solution Explorer, and then click the SharePoint
Solution tab.
We explain the concepts of Features and solutions later in this article, but in brief, certain
elements of the XML files involved are exposed here, as follows:
o A node for the feature.xml file where the name of the folder to be created in
the \12\Template\Features path can be changed. In addition, this node shows the
title, the description, and the scope (by default, set to the level of the site collection).
o A node for the manifest file (elements.xml) where you can set the title and the description
of the Web Part itself.
Note:
The dimmed attributes cannot be changed. For a Web Part project, for
example, there is no way to change the feature.xml file and register an event
handler. Later, I describe a workaround to this problem.
Later in the article, I explain what goes on behind the scenes in more detail. In short, the code is
packaged into a SharePoint solution, added to the solution store at the level of the server farm,
and deployed to the site collection. At this moment, you should be able to add the Web Part to a
page on the targeted site, as shown in Figure 7.
The Visual Studio 2005 Extensions for Windows SharePoint Services 3.0 also supports you in developing
other types of SharePoint solutions. For example, you can create an empty project and then add individual
item templates. Following are the steps to create a simple field type, and to deploy and activate it quickly
and easily within your Windows SharePoint Services development environment.
1. Open Visual Studio 2005, and then create a new SharePoint project.
This time, there is basically nothing created for you. Of course! You picked an empty project! But
what you can do now is add a new item based on the Field Control template, as shown in Figure
8. The one I create is a simple field that captures, stores, and makes a project reference number
available. (There is a small amount of validation logic encapsulated in this process that forces you
to create a three-digit number.)
C#
Print
public override string GetValidatedString(object value)
{
if (value.ToString().Length != 3)
{
throw new SPFieldValidationException
("Only 3 characters allowed!");
}
else
{
return value.ToString();
}
}
3. Before pressing F5, use the properties of the project to configure the way the custom field type is
made available. This time, there are no feature.xml files but there is another XML file created with
the prefix fldtypes that is placed in the \12\TEMPLATE\XML folder. You can set values for
the TypeDisplayName and theTypeShortDescription. Again, use the Debug tab to specify what
site the browser should navigate to when pressing F5 (Figure 9).
Figure 9. Preparing the build and deployment of the custom field type
4. Press F5. Figure 10 shows how the new field becomes part of the list of possible field types. Figure
11 shows the validation code that checks the length of the field value and returns an error
message to the user.
The next example demonstrates how to use the SharePoint Solution Generator to reverse-engineer an
existing (and possibly customized) SharePoint team site with the Visual Studio 2005 Extensions for
Windows SharePoint Services 3.0. The walkthrough shows you how to reverse-engineer one of the 40
templates that are available for download from the MSDN site. Many of these are delivered as .stp files
(the result of the Save As Template command in the browser).
Note:
You can download the templates from Application Templates for Windows SharePoint
Services 3.0.
In this walkthrough, we give the Sports League template to the SharePoint Solution Generator, and
generate a .NET project that contains the individual components of a site definition and the Features that
are involved.
1. Download the Sports League template, install it and upload it in a Site Template gallery of one of
your site collections.
2. Create a site that is based on this newly available template. Figure 12 shows the result of these
actions.
4. Open the SharePoint Solution Generator (Figure 13), click Site Definition, and proceed to the
next step.
5. Type the URL to the site you want to reverse-engineer, or navigate to it by using the tree view.
Specify where to create the Visual Studio 2005 project.
7. When the Solution Generator is finished, you can open the Visual Studio 2005 project. Figure 14
shows the outcome.
8. Press F5 again to make everything available on your development computer. You can configure
many of the details of the different features that represent each of the individual pieces of the
site, as well as the site definition itself by using the SharePoint Solution tab.
Solution is the official term we use now to refer to the distribution package that delivers your custom
Windows SharePoint Services development work to the front-end Web servers, and possibly to the
application servers in your server farm. Figure 15 shows an overview of the various components that can
be packaged in a SharePoint solution. These components include:
.NET assemblies that wrap up the code that drive the solution.
Many solutions involve the delivery of new templates and definitions for sites, lists, libraries, fields,
content types, and more. These definitions are in the form of CAML-based XML files.
And finally, configurations that have to be performed at the level of the front-end Web server (for
example in the web.config files for the registration of Web Parts) can be included.
Figure 15. Anatomy of a SharePoint solution
In addition to all of this, you must include a very important file—the manifest file—to assist Windows
SharePoint Services in the deployment process of the solution. The manifest file is an XML file, which I
describe in more detail later. But in short, the manifest file contains the listing of all assets involved in a
solution, along with target locations for these assets and the various configurations in which they must
occur.
What can be included in the manifest file? A lot—and what follows is a brief explanation of each type of
item. Before starting, it is interesting to mention that the schema definition for the manifest file is included
in the Wss.xsd file that is available in the WSS system folder.
Note:
You can find the WSS system folder in the path C:\Program Files\Common
Files\Microsoft Shared\Web Server Extensions\12.
So you might want to add this to your Visual Studio 2005 environment to get IntelliSense support. Figure
16 shows the main XML elements for a manifest file.
Figure 16. Main XML elements in a solution manifest file
Solution Element
The Solution element is the root element of the manifest file. The SolutionId attribute is an important
element of the file. SolutionId identifies the solution in the solution store (which is part of the
configuration database, discussed later in this article). You identify a solution with a GUID.
Xml
<Solution SolutionId="1de3b0fc-78e9-4fe6-ae63-51ea50109982"
xmlns="http://schemas.microsoft.com/sharepoint/" >
</Solution>
FeatureManifest Element
Features play an important role in many Windows SharePoint Services solutions because they represent
the individual pieces of the solution (such as a field type, a Web Part, a workflow, and so on). You must
represent every Feature that is included in the solution with a FeatureManifest element. The following
code example contains the Feature that advertises a Web Part in a SharePoint site.
Xml
<Solution SolutionId="dda6427b-b880-46c0-a428-10c4bac0ce91"
xmlns="http://schemas.microsoft.com/sharepoint/" >
<FeatureManifests>
<FeatureManifest Location="HelloWorldWebPart_28c3eefe-2c03-4791-9f69-
4405c80e1d92\feature.xml" />
</FeatureManifests>
…
</Solution>
When you deploy the solution to a front-end Web server, all of the Feature-related files are copied to the
location specified here.
Assembly Element
Most of the SharePoint solutions involve one or more .NET assemblies. The Assembly element is used in
the manifest file to make the DLL available on the destination server. Following is an example.
Xml
<Solution SolutionId="dda6427b-b880-46c0-a428-10c4bac0ce91"
xmlns="http://schemas.microsoft.com/sharepoint/" >
…
<Assemblies>
<Assembly Location="HelloWorldWebPart.dll"
DeploymentTarget="GlobalAssemblyCache" >
<SafeControls>
<SafeControl Assembly="HelloWorldWebPart, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=9f4da00116c38ec5" Namespace="MSDN"
TypeName="HelloWorldWebPart" Safe="True" />
</SafeControls>
</Assembly>
</Assemblies>
</Solution>
The first attribute for the Assembly element is Location, which stores the relative path of the DLL in the
solution file. Next, there is the DeploymentTarget attribute, which has two possible
values: GlobalAssemblyCache or WebApplication. GlobalAssemblyCache indicates that the assembly
should be deployed in the global assembly cache; WebApplication tells Windows SharePoint Services to
drop the assembly in the private application folder of the IIS Web application. As discussed
later, WebApplication implies that the solution that is used depends on the trust level that the
administrator sets in the web.config file that is associated with the IIS Web application. Deploying the
assembly in the global assembly cache, which is a fully trusted location, means that as a developer, you do
not have to worry about setting this trust level.
The Web Parts in the solution must be registered as safe controls in the web.config file.
The Assembly element can contain one or more SafeControl elements (grouped together in
a SafeControls element). Each SafeControl element describes the configuration that must be done in the
web.config file.
Another possible set of child elements of the Assembly element are the ClassResource elements
(grouped together in a ClassResources element). Each represents a possible resource that is needed by
the deployed assembly. Examples are resource files, XML files, or pictures.
ApplicationResourceFile Element
The manifest files can contain one or more ApplicationResourceFile elements with a relative path to a
resource file that must be deployed. At the time of deployment, the resource files are copied to the
private application resource folder of the IIS Web Application, as shown in the following code.
Xml
<Solution SolutionId="8f37f0a7-ec35-4a63-9c3d-91205d9a2ac6"
xmlns="http://schemas.microsoft.com/sharepoint/" >
…
<ApplicationResourceFiles>
<ApplicationResourceFile Location="hellowp.resx"/>
<ApplicationResourceFile Location="hellowp.en-us.resx"/>
</ApplicationResourceFiles>
</Solution>
CodeAccessSecurity Element
The CodeAccessSecurity important element is important to include in the manifest file when you want to
grant specific permissions to your code. Later in the article, there is a more detailed discussion about this.
In short, the CodeAccessSecurity element has one or more PolicyItem child elements that each define
the specifics regarding the code access security policy to apply for the solution. There are two parts for a
policy item: the listing of the permissions that are part of it and the assemblies for which these
permissions should play a role.
One or more Assembly elements can play a role in code access security. You must define them one by
one, identifying each by name, version, and full public key.
DwpFile Element
Web Parts must be made available in the Web Part gallery before they can be dropped on the Web Part
Pages. XML files, with either a .dwp extension or a .webpart extension, store the metadata information
that is necessary to make the Web Parts available. The solution manifest file can contain one or
more DwpFile elements that are collected together in the DwpFiles element, with each pointing to one of
these files.
Xml
<DwpFiles>
<DwpFile FileName="hellowebpart.webpart"
Location="hellowebpart.webpart"/>
</DwpFiles>
Resource Element
You can drop resource files in the folder that contains your Feature, and use it from that location.
A Resource element represents such a resource in the solution manifest file. The only attribute to set is
the relative path in the package to the resource file.
SiteDefinitionManifest Element
You use this element when you are deploying a custom site definition.
The SiteDefinitionManifest element has a Location attribute that picks up all the files in the specified
folder and creates the needed folder in the \12\Template\SiteTemplates folder.
The WebTempFile child element deploys the webtemp*.xml file to make the template known to Windows
SharePoint Services.
Xml
<SiteDefinitionManifests>
<SiteDefinitionManifest Location="LitwareSiteTemplate">
<WebTempFile Location="1033\xml\webtempLitware.xml" />
</SiteDefinitionManifest>
</SiteDefinitionManifests>
RootFile Element
Solution files can be copied to a specified folder directly under the \12 folder during deployment by
inserting a RootFile element in the solution manifest file.
TemplateFile Element
The TemplateFile element can be used to define the template files that must be deployed under
the \12\Template folder. An example of the type of file you can deploy in this way is the fldtypes*.xml
file, which defines the details of a custom field type. Use the Location attribute to specify the relative path
to the file.
Earlier in the article, three walkthroughs guided you through the steps of creating and deploying a Web
Part, a custom field type, and a custom site definition. Let’s inspect each of the solutions and the different
files that are included with them.
Let’s first take a look at the SharePoint solution that was generated for the simple Web Part created earlier
in the article. In the \bin\debug folder of the project, you find the .wsp file together with a subfolder
called solution, which contains all of the solution pieces that are packaged in the .wsp file. Figure 17
summarizes all of the components in a Web Part solution.
Figure 17. Components that make up a Web Part solution
There is the folder that contains the three files in the Feature that make the Web Part available to the
users: feature.xml, elementManifest.xml, and HelloWebPart.webpart. There is the assembly with the code
and the manifest file.
Xml
<Solution SolutionId="219eec47-aeae-4ec2-9a2d-b7774a7e92d1"
xmlns="http://schemas.microsoft.com/sharepoint/" >
<FeatureManifests>
<FeatureManifest Location="HelloWebPart_6ad212bb-5425-4d30-aa62-
6acc23d04146\feature.xml" />
</FeatureManifests>
<Assemblies>
<Assembly Location="HelloWebPart.dll"
DeploymentTarget="GlobalAssemblyCache" >
<SafeControls>
<SafeControl Assembly="HelloWebPart, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=9f4da00116c38ec5" Namespace="MSDN"
TypeName="HelloWebPart" Safe="True" />
</SafeControls>
</Assembly>
</Assemblies>
</Solution>
The code contains two main blocks. The first, represented by the FeatureManifests element, tells
Windows SharePoint Services to copy the Feature to the\12\Template\Features folder on the server
where the solution is deployed. The second, represented by the Assemblies element, has two roles: to
deploy the assembly in the global assembly cache, and to define the necessary modifications to the
web.config file with the SafeControl registration.
The second type of solution that was created in the walkthroughs was a custom field type. Navigating to
the solution folder again, you find an assembly and a manifest file at the root, but instead of a Feature
folder, there is a folder named XML, that contains the template file that must be deployed.
Xml
<Solution SolutionId="d5fdc38c-1892-4700-a7e0-723d02d6dfc0"
xmlns="http://schemas.microsoft.com/sharepoint/" >
<TemplateFiles>
<TemplateFile Location="xml\fldtypes_50896c5a-bcfe-47b9-a4da-
5aa78d3c0d3e.xml" />
</TemplateFiles>
<Assemblies>
<Assembly Location="SimpleFieldTypeDemo.dll"
DeploymentTarget="GlobalAssemblyCache" >
<SafeControls>
<SafeControl Assembly="SimpleFieldTypeDemo, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=9f4da00116c38ec5"
Namespace="ProjectReferenceNumber" TypeName="ProjectReferenceNumberField"
Safe="True" />
</SafeControls>
</Assembly>
</Assemblies>
</Solution>
Again, there are two important parts to this code: one deploys the template file to its proper location, and
the second deploys the assembly. The SafeControl entry is not strictly needed unless the field type is
used as a custom field control in publishing pages.
The last type of solution to discuss is the Windows SharePoint Services site exported with the SharePoint
Solution Generator, by using a sports league as an example. Figure 18 displays the many components that
are generated and collected in a .NET project.
Xml
<Solution SolutionId="c2f14355-caea-4e02-b2fb-be198b71a99f"
xmlns="http://schemas.microsoft.com/sharepoint/" >
<FeatureManifests>
<FeatureManifest Location="LeagueCalendar_2a46379a-0cc6-4f0f-b901-
d69c688270d5\feature.xml" />
<FeatureManifest Location="PlayersList_63daf9b3-2d56-4b80-b235-
c064b9b14d38\feature.xml" />
<FeatureManifest Location="SharedDocuments_3dc03f6a-7abe-4cc7-8995-
7d799bf1fa55\feature.xml" />
<FeatureManifest Location="Teams_254d82e9-f759-4e29-86f0-
7a5870fc7a7d\feature.xml" />
<FeatureManifest Location="MSDNLeagueSiteTemplate_af2531ff-18bf-45f9-
b47c-f9e820f570d3\feature.xml" />
<FeatureManifest Location="MSDNLeagueSiteTemplate_d8e211da-abed-4556-
87c9-0ceb6fa1220f\feature.xml" />
</FeatureManifests>
<Assemblies>
<Assembly Location="MSDNLeagueSiteTemplate.dll"
DeploymentTarget="GlobalAssemblyCache" >
<SafeControls>
<SafeControl Assembly="MSDNLeagueSiteTemplate, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=a203fc97bcb29c46"
Namespace="MSDNLeagueSiteTemplate" TypeName="MSDNLeagueSiteTemplate"
Safe="True" />
</SafeControls>
</Assembly>
</Assemblies>
<SiteDefinitionManifests>
<SiteDefinitionManifest Location="MSDNLeagueSiteTemplate_072c8ac2-012e-
405d-b436-a4809fcb6c1f">
<WebTempFile Location="1033\xml\webtempMSDNLeagueSiteTemplate_ee077f02-
b4a0-45ba-829c-8eeb1991cf90.xml" />
</SiteDefinitionManifest>
</SiteDefinitionManifests>
</Solution>
The section of code that differs from the previous examples is the last part with
the SiteDefinitionManifests element. The SiteDefinitionManifest element deploys the site definition in
the \12\Template\SiteTemplates folder, and the WebTempFile element does the same for the
webtemp*.xml file.
A final example is the definition of a custom list. This is shown with a short walkthrough that
demonstrates how the Visual Studio 2005 Extensions for Windows SharePoint Services 3.0 can help you in
the initial stages.
1. Navigate to one of your sites and create a list based on the custom list template.
2. Name the list Employees, and then add the following columns: First Name, Last
Name (changing the Title column), Department, and Telephone Number.
You can now use the SharePoint Solution Generator to generate the bulk of the custom list
definition.
3. Open the SharePoint Solution Generator, and on the first page, select List Definition.
4. Enter the URL of your site and select the list instance created at the beginning of this
walkthrough.
5. Provide the location where you want to create the Visual Studio project, and then click Finish to
start the generation process.
6. Let’s now construct the Feature for this new list template. Create a folder on your file system in a
location you choose, with a Features folder as a subfolder.
7. Under the Features folder, create another subfolder named EmployeesList. Copy the Employees
folder from the .NET project folder into it.
8. At the level of the EmployeesList folder, create a feature.xml file containing the following XML.
Xml
<Feature Id="{489C77F1-B064-408e-9B85-029A33BDF9D7}"
Title="Employees"
Description="This feature provides support for creating an Employee
List."
Version="1.0.0.0"
Scope="Web"
Hidden="FALSE"
xmlns="http://schemas.microsoft.com/sharepoint/">
<ElementManifests>
<ElementManifest Location="ListTemplates\Employees.xml"/>
<ElementFile Location="Employees\allitems.aspx" />
<ElementFile Location="Employees\dispform.aspx" />
<ElementFile Location="Employees\editform.aspx" />
<ElementFile Location="Employees\newform.aspx" />
<ElementFile Location="Employees\schema.xml" />
</ElementManifests>
</Feature>
9. Create a ListTemplates folder under the EmployeesList folder, and then create the Employees.xml
in it containing the CAML for the list template.
Xml
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<ListTemplate
Name="Employees"
Type="10100"
BaseType="0"
OnQuickLaunch="TRUE"
SecurityBits="11"
DisplayName="Employees"
Description="Employees List Type"
Image="/_layouts/images/CHNGCOL.GIF"/>
</Elements>
10. Open the schema.xml in the Employees folder, and make sure that the Type attribute for the root
element matches the number you used in the Timesheets.xml for the type (in the example,
10100). Also open each of the .aspx pages, and then remove the first line containing the
comment.
You now have the Feature ready. Next, you must package all of this into a SharePoint solution.
1. Create a manifest file at the root level of the folders you created earlier. It is a simple task because
there is no code involved.
Xml
<Solution SolutionId="{B2BE6294-D62F-4f14-9266-7C37AD2B9DBA}"
xmlns="http://schemas.microsoft.com/sharepoint/" >
<FeatureManifests>
<FeatureManifest Location="EmployeesList\feature.xml" />
</FeatureManifests>
</Solution>
2. Create a .ddf file at the same level as the manifest file to package everything into a solution file.
3. ;
4. ; *** .ddf file for generating SharePoint solution
5. ;
6. .OPTION EXPLICIT ; Generate errors
7. .Set CabinetNameTemplate=Employees.wsp
8. .set DiskDirectoryTemplate=CDROM ; All cabinets go in a single
directory
9. .Set CompressionType=MSZIP;** All files are compressed in cabinet files
10. .Set UniqueFiles="ON"
11. .Set Cabinet=on
12. .Set DiskDirectory1=Package
13.
14. ; *** the manifest file
15. manifest.xml manifest.xml
16.
17. ; *** the feature files
18. Features\EmployeesList\feature.xml EmployeesList\feature.xml
19. Features\EmployeesList\ListTemplates\Employees.xml
EmployeesList\ListTemplates\Employees.xml
20. Features\EmployeesList\Employees\AllItems.aspx
EmployeesList\Employees\AllItems.aspx
21. Features\EmployeesList\Employees\DispForm.aspx
EmployeesList\Employees\DispForm.aspx
22. Features\EmployeesList\Employees\EditForm.aspx
EmployeesList\Employees\EditForm.aspx
23. Features\EmployeesList\Employees\NewForm.aspx
EmployeesList\Employees\NewForm.aspx
Features\EmployeesList\Employees\schema.xml
EmployeesList\Employees\schema.xml
24. Package everything into the .wsp file, add the solution to the solution store, and then deploy it
globally by using the following Stsadm calls (typically contained within a batch file).
You can now try out your work by activating the Feature from the Site Features page in one of your sites,
and create a new list instance based on the new template.
Contents
Managing Solutions
Conclusion
Additional Resources
This article is a continuation of Development Tools and Techniques for Working with Code in Windows
SharePoint Services 3.0 (Part 1 of 2).
A SharePoint solution must be added to the solution store that is available in the server farm. The solution
store is part of the configuration database and stores the various .wsp files. You add the solution to the
store via the Stsadm.exe command-line utility or by using a programmatic approach.
Using Stsadm.exe
You can call Stsadm.exe with the addsolution operation by specifying the relative path to the .wsp file.
Following is a sample.
Note:
If you are localizing the solution, you can also use a third parameter: lcid.
In another approach, you can create a .NET Framework application that talks to the object model that is
exposed by Windows SharePoint Services. You can add a SharePoint solution to the solution store by
using one line of code as follows.
C#
Print
SPSolution solution = SPFarm.Local.Solutions.Add(@"C:\Package\MySol.wsp");
The SPFarm class in the Microsoft.SharePoint.Administration namespace that enables you to connect
to the server farm (either one that is created locally or one you joined remotely). You can populate
an SPSolutionCollection object with new solutions by calling the Add method, as long as it is either an
instance of anSPSolution class or the path to the SharePoint solution file. An SPSolution instance is
returned. Numerous properties and methods are exposed at this level.
Deploying a Solution
Your next step is to actually deploy the solution on one or more Web servers that are Windows
SharePoint Services–enabled, either as front-end Web servers or as application servers. You can deploy
the solution in three ways:
By using Stsadm.exe
Using Stsadm.exe
Stsadm.exe has an option, deploysolution, which you can use to deploy the solution via a command
prompt. The name of the solution in the solution store is one of the parameters and the URL of the site
collection you are targeting. The following is an example.
Instead of targeting one site collection, you also have the option to push your solution to every site
collection available within the server farm. You use theallcontenturls parameter for this as follows.
By default, the solution is immediately deployed, but you can also schedule the deployment by using
the time parameter.
The allowgacdeployment and allowcaspolicies parameters are also very important and are discussed later
in more detail. In short, allowgacdeployment is true by default and enables Windows SharePoint Services
to deploy the assemblies in the global assembly cache. The allowcaspolicies parameter enables the
creation of a custom code access security (CAS) policy file and the activation of it in the Web.config file of
the targeted site collection.
Deploying a Solution via the Windows SharePoint Services 3.0 Object Model
At the level of the SPSolution instance, you can use two methods to programmatically deploy your
solution: Deploy and DeployLocal. Both can accept a collection ofSPWebApplication objects populated
with the Internet Information Services (IIS) Web applications that you want to target with the deployment.
You populate the collection as follows.
C#
Print
Collection<SPWebApplication> webapps = new Collection<SPWebApplication>();
SPWebApplication webapp =
SPWebApplication.Lookup(new Uri("http://wss.litwareinc.com"));
webapps.Add(webapp);
Both methods also allow for the deployment of the assemblies included in the Web Part solutions to the
global assembly cache. The difference between the two methods is that you can call Deploy with
a DateTime parameter that stores the exact moment you want the solution to be deployed, as shown in
Figure 20.
C#
Print
solution.Deploy(DateTime.Now.AddMinutes(5), true, webapps, true);
C#
Print
solution.DeployLocal(true, webapps, true);
Administrators can also navigate to the Operations page in Central Administration and use Solution
Management to deploy the Windows SharePoint Services solution to an IIS Web application either
immediately or at a specific time in the future.
Administrators receive a warning when the manifest file that is part of the solution requires assemblies to
be deployed in the global assembly cache.
Deploy .NET assemblies in the private application folder instead of the global assembly cache.
Add code access security permissions to the solution that must be applied during the
deployment.
Deviate from the names used by default for the Feature folders.
Associate Feature event handlers to certain types of Windows SharePoint Services solutions, such
as Web Part solutions.
Add resources (XML files, pictures, and so on) to the solution package.
1. Collect all individual solution files in a folder. There are no concrete guidelines about how you
should do this, but a best practice is to separate the different types of solution files into their own
subfolders.
2. Create a .ddf file (abbreviation of Diamond Directive File) that defines the structure of the
Windows SharePoint Services solution file. This file contains the list of individual solution files that
determine the output .wsp file.
3. Execute the command-line utility MakeCab.exe with the .ddf file as input and the .wsp file as
output.
Windows SharePoint Services 3.0 offers developers the option to execute custom code when a Feature is
installed, activated, deactivated, or uninstalled. An example is a Web Part that is dependent on a specific
task list. When the Web Part Feature is activated, custom code can check whether this task list is part of
the lists within the site. If not, the code creates the list, and then removes the list when the Feature is
deactivated. The custom code is wrapped into a .NET assembly referred to as the Feature Receiver
Assembly.
This walkthrough assumes you have a Web Part project created, as discussed in Development Tools and
Techniques for Working with Code in Windows SharePoint Services 3.0 (Part 1 of 2). When the Web Part
Feature is installed, activated, deactivated, or uninstalled, Windows SharePoint Services fires asynchronous
events. You can handle these events in a custom .NET assembly by creating a .NET class that inherits from
the abstract Microsoft.SharePoint.SPFeatureReceiver class. Following are the class from the sample and
the four members to implement.
C#
Print
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
namespace MSDN.Samples
{
public class MSDNTaskListEventHandler: SPFeatureReceiver
{
public override void FeatureActivated(SPFeatureReceiverProperties
properties)
{
SPSite sitecollection = (SPSite)properties.Feature.Parent;
SPWeb web = sitecollection.RootWeb;
try
{
// -- Check if list exists.
SPList list = web.Lists["MSDN Tasks"];
}
catch
{
// -- If not, create the list.
web.Lists.Add("MSDN Tasks", "A custom list",
SPListTemplateType.Tasks);
}
}
The coding work results in two assemblies. One assembly contains the code delivering the Web Part. A
second assembly contains the previous code. At the moment of writing, Visual Studio Extensions for
Windows SharePoint Services 3.0 does not allow you to connect the event handler with the Web Part
Feature definition file. In addition, Web Part assembly must be deployed in the private application folder
instead of the global assembly cache. Because of this, you must create the solution package manually.
Note:
In the following steps, the way you organize the different files representing the solution
components can be adapted to your own preferences and can be part of the Visual Studio 2005
solution.
Create a folder with two subfolders to collect all of the solution components. A first subfolder stores the
assemblies (named Assemblies in this article), and the second subfolder stores the different XML files
defining the Features (named Features in this article). Copy the Web Part assembly and the event handler
assembly into the Assemblies folder.
Create a subfolder under the Features folder for every Feature that must be included in the SharePoint
solution. There is only one Feature for this walkthrough. Assume that it is called MSDNTaskCreator; the
Features folder contains a subfolder with that name. At the root of this folder, add a feature.xml file that
contains the following XML.
Xml
<Feature Title="MSDNTaskCreator"
Id="55312295-a323-4333-b875-1bbe8ef7fd04"
Description="Small Web Part creating a custom task item"
Version="1.0.0.0" Scope="Site" Hidden="FALSE"
ReceiverAssembly="MSDNFeatureEventhandlers, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=5e5a470a5445a8f1"
ReceiverClass="MSDN.Samples.MSDNTaskListEventHandler"
DefaultResourceFile="core"
xmlns="http://schemas.microsoft.com/sharepoint/">
<ElementManifests>
<ElementManifest Location="elementManifest.xml" />
<ElementFile Location="MSDNTaskCreator.webpart" />
</ElementManifests>
</Feature>
How does this XML deviate from the XML that is generated with Visual Studio Extensions for Windows
SharePoint Services 3.0? Two additional attributes are added to the feature.xml file:
The ReceiverAssembly attribute contains the full strong name of the .NET assembly that contains
the event handler code.
The ReceiverClass attribute stores the full name of the class within that assembly.
You must create a manifest file in the root folder. It is different from the one that is generated by Visual
Studio Extensions for Windows SharePoint Services 3.0. Following are the contents.
Xml
<Solution SolutionId="d63d0395-96a4-449e-83ce-5f7239bbd3ad"
xmlns="http://schemas.microsoft.com/sharepoint/" >
<FeatureManifests>
<FeatureManifest Location="MSDNTaskCreator\feature.xml" />
</FeatureManifests>
<Assemblies>
<Assembly Location="MSDNTaskCreator.dll"
DeploymentTarget="WebApplication" >
<SafeControls>
<SafeControl Assembly="MSDNTaskCreator, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=9f4da00116c38ec5" Namespace="MSDN.Samples"
TypeName="MSDNTaskCreator" Safe="True" />
</SafeControls>
</Assembly>
<Assembly Location="MSDNFeatureEventHandlers.dll"
DeploymentTarget="GlobalAssemblyCache" />
</Assemblies>
</Solution>
Notice that the name of the Feature no longer includes a GUID. The first assembly element has an
attribute named DeploymentTarget, with the valueWebApplication instead of GlobalAssemblyCache.
A second assembly element with the definition of the .NET assembly contains the event handler code to
deploy in the global assembly cache.
Now we can create the .ddf file named, in this case, .wsp_structure.ddf. Create it directly in the
DeploymentFiles folder. First, add the following header information.
;
; *** .ddf file for generating SharePoint solution.
;
.OPTION EXPLICIT ; Generate errors
.Set CabinetNameTemplate=MSDNTaskCreatorWebPart.wsp
.set DiskDirectoryTemplate=CDROM ; All cabinets go in a single directory
.Set CompressionType=MSZIP;** All files are compressed in cabinet files
.Set UniqueFiles="ON"
.Set Cabinet=on
.Set DiskDirectory1=Package
DiskDirectory1 is set to Package. This is the directory containing the generated .wsp file.
The second part of the .ddf file defines the structure of the package.
The .ddf file is input for MakeCab.exe, a tool you can get by installing the Microsoft Cabinet SDK
(C:\Program Files\Microsoft Cabinet SDK) and it is also part of the Smart Devices SDK
(C:\Program Files\Microsoft Visual Studio 8\SmartDevices\SDK\SDKTools).
Note:
You can download the Microsoft Cabinet SDK from Internet Client SDK: Microsoft Cabinet
SDK.
To facilitate the packaging and deployment, create a batch file with the following content.
"%MakeCabTool%" /f wsp_structure.ddf
"%SPAdminTool%" -o addsolution -filename package\ MSDNTaskCreatorWebPart.wsp
"%SPAdminTool%" -o deploysolution -name MSDNTaskCreatorWebPart.wsp -immediate
-allowGACDeployment -url http://moss.litwareinc.com
The first two lines are the settings of the paths to the Makecab and Stsadm command-line tools. Next,
there is the line creating the solution package.
makecab.exe /f wsp_structure.ddf
As a result of the execution, MSDNTaskCreatorWebPart.wsp appears in the Package folder. The next line
adds the MSDNTaskCreatorWebPart.wsp to the solution store in your server farm by executing the
following command.
The final line in the batch file is the deployment of the solution to one of your site collections. You can use
the Solution Management page under the Operations tab in Central Administration, or open a Command
Prompt window again and execute the following command line.
The Web Part Feature is installed but not activated. To activate the Feature, open the Site Collection
Features page, and then click the Activate button. Because there is code that executes when
the FeatureActivated event fires, the MSDN Task list is created. Deactivating this feature removes this
task list from the root site of the site collection.
We can show all of this with a small Web Part that connects to a Web service that returns weather
information for a specific city. If you build and deploy this Web Part by using Visual Studio 2005
Extensions for Windows SharePoint Services 3.0, the .NET assembly is deployed in the global assembly
cache. You cannot intervene in this process on your development computer to configure the solution
generation process and deployment differently. Because of the deployment in the global assembly cache,
your Web Part gets full trust and does not have any security problems connecting to the Web service.
This scenario works if administrators allow your Web Part assemblies to be deployed in the global
assembly cache. However, your Web Part assembly can often end up in the private \bin folder of the IIS
Web application. As a Web Part developer, you then depend on the trust level set in the web.config file by
administrators. In the end, you can encounter security problems with Web Parts that perform functions
similar to our weather Web Part, as described in the following walkthrough.
To deploy the Web Part assembly in the private application folder of the IIS Web application instead of
the global assembly cache (which is the default when using Visual Studio 2005 Extensions for Windows
SharePoint Services 3.0), you can make a change in the manifest file that will enforce this. You can set
theDeploymentTarget attribute at the level of the Assembly element to WebApplication instead
of GlobalAssemblyCache, as shown in the following example.
Xml
<Solution SolutionId="1de3b0fc-78e9-4fe6-ae63-51ea50109982"
xmlns="http://schemas.microsoft.com/sharepoint/" >
<FeatureManifests>
<FeatureManifest Location="WeatherWebPart\feature.xml" />
</FeatureManifests>
<Assemblies>
<Assembly Location="WeatherWebPart.dll"
DeploymentTarget="WebApplication" >
<SafeControls>
<SafeControl Assembly="WeatherWebPart, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=9f4da00116c38ec5" Namespace="WeatherWebPart"
TypeName="WeatherWebPart" Safe="True" />
</SafeControls>
</Assembly>
</Assemblies>
</Solution>
Next, you must create the Windows SharePoint Services solution manually. The following .ddf file shows
how to package the different components that make up the Web Part solution.
.OPTION EXPLICIT
.Set CabinetNameTemplate=WeatherWebPart.wsp
.set DiskDirectoryTemplate=CDROM ; All cabinets go in a single directory
.Set CompressionType=MSZIP ;** All files are compressed in cabinet files
.Set UniqueFiles="OFF"
.Set Cabinet=on
.Set DiskDirectory1=Package
manifest.xml manifest.xml
assemblies\WeatherWebPart.dll WeatherWebPart.dll
Features\WeatherWebPart\feature.xml WeatherWebPart\feature.xml
Features\WeatherWebPart\elementManifest.xml
WeatherWebPart\elementManifest.xml
Features\WeatherWebPart\WeatherWebPart.webpart
WeatherWebPart\WeatherWebPart.webpart
A simple call to Makecab.exe with the .ddf file as input generates the Windows SharePoint Services
solution.
makecab.exe /f WeatherWebPart.ddf
You can add the solution to the solution store by executing the following command in a Command
Prompt window.
Now, navigate to Central Administration and the Solution Management page. From here you can deploy
the solution. Notice that there is no warning because the manifest file does not require the assembly to
be deployed in the global assembly cache. Proceed and deploy the solution to one of your IIS Web
applications. It’s a good idea to verify in the physical folder that is associated with the IIS Web application
(which is located, by default, in Inetpub\wwwroot\wss\VirtualDirectories\IIS Web application
name) that the assembly is available in the \bin folder.
Assuming the trust level in the web.config file is not set to Full, you get an exception if you try to run your
weather Web Part, as shown in Figure 22.
In other words, your Web Part is not granted the permission to communicate with the Web service. How
do you solve this? One way is to raise the trust level in the web.config file to Full, but this is risky. From the
moment you raise the trust level, all of the privately deployed assemblies get the same basic permissions
as the assemblies that are deployed in the global assembly cache. A better solution is to request the
permissions that are needed to run the Web Part correctly in SharePoint pages and include that demand
inside the manifest file. Administrators who deploy the solution will receive a notification that specific
requests for permissions are pending, and they can decide whether to grant these permissions. When
proceeding, a copy is made of the policy file that is currently activated, and the requested permissions for
the Web Part are added. This new policy file becomes the one activated in the web.config file. Now we can
examine all of these steps in more detail.
One piece of information is already available. You have the full details of the required permission
(discussed previously). Another piece of information is the full public key blob of the assembly you’re
working with. To retrieve this information, open a Command Prompt window, and execute the following
command.
The result is a text file with the full public key of the assembly in question. The tool used is secutil.exe,
which is part of the .NET Framework SDK.
Next, open the manifest file, and add the following CodeAccessSecurity element (a good location is
between the FeatureManifests and the Assemblies elements).
Xml
<CodeAccessSecurity>
<PolicyItem>
<PermissionSet class="NamedPermissionSet" version="1"
Description="My webpart's permission set">
<IPermission class="AspNetHostingPermission" version="1"
Level="Minimal"/>
<IPermission class="SecurityPermission" version="1"
Flags="Execution" />
<IPermission version="1" Unrestricted="True"
class="Microsoft.SharePoint.Security.SharePointPermission,
Microsoft.SharePoint.Security, Version=12.0.0.0, Culture=neutral,
PublicKeyToken=71e9bce111e9429c" />
<IPermission class="System.Net.WebPermission, System,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Unrestricted="True"
version="1">
<ConnectAccess>
<URI uri="$OriginHost$"/>
<URI uri="http://moss:95/webservices/.*"/>
</ConnectAccess>
</IPermission>
</PermissionSet>
<Assemblies>
<Assembly Name="WeatherwebPart" Version="1.0.0.0"
PublicKeyBlob="0x002400000480000094000000060200000024000052534131000400000100
01000DAF8ED8D945CD2ABB2EE7953A6039B791A725F11B4588AC6D70B3E0648F955E9ED4C3C43
CB044B8B0E8A6FF4D4FFBE9E3B9297D45F688A7264534E12414E17539305207EC961DA94DF294
E7722CCD9BDBFC95A896E996F57156705D281EC39280BD604E87724556AF5807D146963F19F5B
43DB69E1F22695463153A553260D2" />
</Assemblies>
</PolicyItem>
</CodeAccessSecurity>
In the previous code, the IPermission and Assembly element areas are important to review. First,
the IPermission element asks for permission to communicate with the Web service (we assume that this
Web service is hosted on http://moss:95 IIS Web Application). Next, the Assembly element
contains the details of the assembly in question: the name, version, and blob you must retrieve from the
keyblob.txt file that is generated via the secutil.exe utility.
When these changes are applied to the manifest file, you must regenerate the Windows SharePoint
Services solution and re-add it to the solution store. When you deploy the solution, you will notice a
warning at the bottom of the page (see Figure 23) that indicates that the solution contains a code access
security policy that will take effect if you continue to deploy the solution. If the administrators do not see
a problem with this, they can continue and the Web Part is made available.
Figure 23. Deploying a Web Part solution with a code access security policy
If you followed all of the earlier steps correctly, the weather Web Part works again as before. Behind the
scenes, you notice a new entry in the securityPolicy element of the web.config file that looks like the
following.
Xml
<securityPolicy>
<trustLevel name="WSS_Medium" policyFile="C:\Program Files\Common
Files\Microsoft Shared\Web Server
Extensions\12\config\wss_mediumtrust.config" />
<trustLevel name="WSS_Minimal" policyFile="C:\Program Files\Common
Files\Microsoft Shared\Web Server
Extensions\12\config\wss_minimaltrust.config" />
<trustLevel name="WSS_Custom" policyFile="C:\Program Files\Common
Files\Microsoft Shared\Web Server
Extensions\12\config\wss_custom_wss_minimaltrust.config" />
</securityPolicy>
The new level—WSS_Custom—is now the active trust level in the web.config file.
Managing Solutions
Windows SharePoint Services 3.0 also offers support for managing SharePoint solutions. You can retract
solutions, remove solutions from the solution store, and upgrade solutions in several ways.
Retracting Solutions
When you retract a SharePoint solution, Windows SharePoint Services physically removes all of the
solution components from the location where they were deployed. Retracting a solution can be
completed in three ways:
By using Stsadm.exe
Using Stsadm.exe
The option named retractsolution accepts several parameters. The name of the solution is a required
parameter. Optionally, you can specify the URL for a specific IIS Web application and site collection, or
remove the solution from all places where it was deployed via the allcontenturls parameter.
The time parameter schedules the retraction for a job definition. You use the immediate parameter when
you want to perform actions directly.
After the solution is available in the solution store, you access it via the solution management page in
Central Administration. From here you can start the process of retracting a solution, as shown in Figure 24.
A final approach to retracting a solution is through the Windows SharePoint Services 3.0 object model.
The SPSolution class exposes the Retract and RetractLocalmethods. You can use Retract to schedule
the retracting of the solution. Both methods offer the option to retract the solution from all or from only a
specific collection of SPWebApplication objects. The following code example retracts a Web Part
solution from all IIS Web applications that are available on a local computer.
C#
Print
SPSolution solution = SPFarm.Local.Solutions["hellowebpart.wsp"];
solution.RetractLocal();
You can retract a solution that delivers Web Parts by using one of the previously mentioned options.
However, you should notice that retracting the Web Part does not remove the .webpart entry from the
Web Part gallery. As a consequence, the Web Part remains advertised in the Add a Web Part dialog box,
and users can still see it. However, when users add the Web Part to a page, errors are shown because the
Web Part is no longer registered as a safe control, and the assembly is removed from either the local bin
folder or the global assembly cache. Also notice that retracting a Web Part solution causes existing Web
Part instances to stop working and displays an error in the SharePoint pages. To solve this, you can have a
deactivation callout that deletes the .webpart file from the Web Part Gallery.
Retracting Schema-based Solutions
You must take care when retracting schema-based solutions, such as custom list definitions. Many
instances can exist, and you probably don't want to break them. Therefore, best practice when instances
of these types of solutions are available is to make the Feature invisible to the user rather than retracting
the solutions. A small walkthrough in the section on upgrading solutions, later in the article, shows the
different steps.
Windows SharePoint Services solutions that are no longer deployed can be removed from the solution
store. You can do this in three ways:
By using Stsadm.exe
Using Stsadm.exe
Administrators can now launch the command-line utility Stsadm.exe, and then execute
the deletesolution option. The name parameter is the name of the solution and is required. Use the
following command to remove a solution.
On the solution management page, which is accessible via the Operations tab in Central Administration,
you can remove a solution that is no longer deployed. Just click the solution name and use the Remove
Solution button on the toolbar.
You can also remove the solution by calling the Remove method at the level of
the SPSolutionCollection object. This collection is exposed via the SPFarm class, either for the local farm
or from the joined farm. The following code removes a solution from the solution store.
SPFarm.Local.Solutions.Remove("hellowebpart.wsp");
Upgrading Solutions
The last option for managing SharePoint solutions is to upgrade deployed solutions to new versions. It is
important to understand that the versioning is not performed at the level of the Windows SharePoint
Services solution. The actual versioning is performed at the level of the solution components (the Feature,
the assemblies, and so on).
Assume that version 1.0.0.0 of the MySolution.wsp is added to the solution store and deployed to one or
more IIS Web applications. A second version of the Windows SharePoint Services solution must have the
same SolutionID for an upgrade to succeed. The second version is upgraded by calling the Stsadm.exe
command-line utility with the option upgradesolution. In the solution store, you provide the name of the
solution to upgrade, the new version of the solution, and then specify the options to either schedule the
upgrade or have it upgrade immediately. You also specify the options to allow deployment in the global
assembly cache and allow for custom code access security policies.
When discussing guidelines for upgrading SharePoint solutions, we must make the distinction between
code-based solutions (such as Web Parts) and schema-based solutions (such custom list definitions).
Upgrading Web Part solutions Web Parts are typical examples of code-based solutions.
Upgrading a code-based solution often involves replacing the assembly in the private application
folder of the IIS Web application or the global assembly cache with an updated version of the
assembly. Figure 26 summarizes the possible upgrade paths.
The upgrade process is a bit more complex when the strong name of the assembly is changed,
typically by upgrading the version number from perhaps 1.0.0.0 to 2.0.0.0. If no Web Part
instances have been created within the sites, you will not have a problem. The entry in the Web
Part gallery is updated with the new .webpart file, and the new version of the assembly is dropped
in either the bin folder or the global assembly cache. New additions of the Web Part to the pages
reflect the new functionality.
However, users can experience errors when there are existing instances of the older version of the
Web Part on the pages, and you decide to perform an upgrade. These instances are still looking
for the first version of the assembly. When using the upgradesolution option, the older version
of the assembly is actually removed, as well as the entry in the safeControls section of the
web.config file.
So your approach is a combination of upgrading the Web Part solution with a new version of the
assembly combined with two additions in the web.config of the IIS Web application hosting the
SharePoint site. These two additions are, first a SafeControl element for the first version of the
assembly, and second, abindingRedirect ordering ASP.NET to bind to the second version of the
assembly, in case there is the request for the first version.
Walkthrough: Upgrading a Web Part Project
1. Start by building a small Web Part project that outputs a string that displays, for example,
the version information. You can use Visual Studio 2005 Extensions for Windows
SharePoint Services 3.0 to get started, but you must perform the packaging and
deployment manually. We advise a project structure such as the one depicted in Figure
27. All of the techniques previously discussed regarding the manual packaging of a
SharePoint solution are used here.
2. Deploy the solution and activate the Feature in the site collection so that you can add the
Web Part to one of your pages (see Figure 28).
4. Open the .webpart file and update the version number for the type element.
5. Build the project and rebuild the SharePoint solution file. Upgrade the solution by calling
the following from either a batch file or a command prompt.
6. Refresh the page with the Web Part instance. Figure 29 shows the error displayed as well
as a new instance nicely reflecting the change in the output.
1. Add the SafeControl element for version 1.0.0.0 in the web.config file.
Xml
<SafeControl Assembly="VersionDemo, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=9f4da00116c38ec5"
Namespace="MSDN.Samples" TypeName="VersionDemo" Safe="True"
/>
Xml
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-
com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="VersionDemo"
publicKeyToken="9f4da00116c38ec5" culture="neutral" />
<bindingRedirect oldVersion="1.0.0.0"
newVersion="2.0.0.0" />
</dependentAssembly>
…
</assemblyBinding>
</runtime>
8. Refresh the page containing the two Web Part instances. Figure 30 shows the end result.
The first version of the Web Part now also works against the 2.0.0.0 version of the
assembly.
Let's return to the Employees list template we created and deployed as a SharePoint solution
earlier in the article.
Assume that users have created many instances of this list. The decision has been made to make
changes or possibly to completely remove the list definition. As mentioned, you cannot simply
remove the solution files from the SharePoint computer. You need to keep them working,
although invisible, for the administrators and users. Notice that this approach is also the one to
take as an alternative to retracting the solution, as discussed earlier.
1. Open the folder containing the solution components of the list definition, and then open
the feature.xml file.
2. Change the Hidden attribute of the Feature element to the value TRUE.
Xml
<Feature Id="{489C77F1-B064-408e-9B85-029A33BDF9D7}"
Title="Employees"
Description="This feature provides support for creating an
Employee List."
Version="1.0.0.0"
Scope="Web"
Hidden="TRUE"
xmlns="http://schemas.microsoft.com/sharepoint/">
<ElementManifests>
<ElementManifest Location="ListTemplates\Employees.xml"/>
<ElementFile Location="Employees\allitems.aspx" />
<ElementFile Location="Employees\dispform.aspx" />
<ElementFile Location="Employees\editform.aspx" />
<ElementFile Location="Employees\newform.aspx" />
<ElementFile Location="Employees\schema.xml" />
</ElementManifests>
</Feature>
This hides the Feature from the administration pages, but you must also hide it on the
Create page.
Xml
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<ListTemplate
Name="Employees"
Type="10100"
BaseType="0"
OnQuickLaunch="TRUE"
SecurityBits="11"
DisplayName="Employees"
Description="Employees List Type"
Hidden="TRUE"
Image="/_layouts/images/CHNGCOL.GIF"/>
</Elements>
If you want to retract only the solution, the previous steps are enough.
If, however, you want to replace the list definition with a new version, you’ll need to add the
following to the solution package:
o A new version of the Feature (with all of the related files) marked with a different GUID.
o An expanded manifest file with the installation steps for both the original (and soon
hidden) version, and the new version of the Feature.
o An expanded .ddf file containing the entries for packaging the new Feature and the
previous version in the .wsp file.
In both scenarios, you must recreate the SharePoint solution file and deploy it by using
the upgradesolution option for Stsadm, as discussed previously.
Conclusion
The concept of solutions in the world of Windows SharePoint Services is extremely important for
developers and administrators to understand. Developers who build applications and extend SharePoint
sites in numerous ways must package the solution components in SharePoint solution files and deliver
those to administrators. Administrators have various options for delivering the solution to the users of the
SharePoint sites. This article discusses new options that are available for pushing the solutions from a
central solution store to the front-end Web servers and application servers. The article also discusses
techniques for maintaining and upgrading the deployed solutions.