Chapter 7. Packaging, deployment, and security – SharePoint 2010 Web Parts in Action

Chapter 7. Packaging, deployment, and security

 

 

Using Visual Studio 2010 to develop your Web Parts makes it easy to create, package, and add your solutions to SharePoint. In previous versions of SharePoint and Visual Studio, this process wasn’t automated, which forced developers to learn how to script SharePoint solution deployment. Even though the new toolset helps you with packaging and deployment during development, you’ll eventually deploy the solution to a nondevelopment environment. So it’s important to know the basic administrative tasks for SharePoint solutions and Features. Knowing how and when to upgrade solutions is also an important issue. SharePoint 2010 has new features that make the upgrading process easier and more efficient. Taking advantage of these features allows for more agile development and reduces server maintenance and downtime.

Sandboxed solutions in SharePoint make deployment easier and allow you to create custom applications in a controlled manner. Sandboxed solutions also introduce a new security scope for SharePoint applications with a limited security policy. Previous SharePoint versions had only one level where the application was fully trusted (deployed to the global assembly cache, or GAC) and one level in partial trust (deployed in the local web application bin folder, which required a lot of configuration). The level of security and type of deployment is determined by the needs and use of the application. This chapter discusses the various options using a set of examples.

7.1. Solution packages

All solutions, not just Web Parts, in SharePoint should be packaged as Windows SharePoint Solutions Package (WSP) files. These solution packages are compressed files containing all the files required for the solution and the Features that are bundled into the package. You add solution packages from a single point into a SharePoint farm and then deploy them out to all the servers in your farm.

A solution package most often contains one or more Features. A Feature can be scoped to different levels of the SharePoint farm depending on where it’s going to be used. Features contain definitions for Web Parts, lists, content types, and all other SharePoint artifacts. A Feature can also contain property values that will be promoted to SharePoint. A Feature must be activated before you use it, and it can be deactivated to remove the functionality. Each Feature can contain a Feature receiver, also known as event receiver, which can be used to execute code during installation and activation.

Only trusted and safe Web Parts and controls can be used by SharePoint. Each package contains information about its containing Web Parts and controls and their trust level. During deployment, this trust level is applied to the web applications.

7.1.1. Windows SharePoint package files

WSP files are CAB compressed files containing all the files needed to install solutions into a SharePoint farm. So far in this book you’ve been using WSP files to deploy your solutions. Visual Studio 2010 automatically packages the Features and manifests to a WSP file and then deploys it into SharePoint when you press F5. When debugging is stopped, the WSP file is retracted from SharePoint (unless otherwise configured).

These packages are one of the key features of the SharePoint infrastructure and make the deployment of Features and applications an easy task, considering the complex environment. The WSP files are uploaded to the SharePoint configuration database, and when they’re installed, the files are unpacked on each application and web server in the farm. When you add a new server to the SharePoint farm, SharePoint knows which packages are installed and unpacks them onto the new server, without you having to interact with the process. Compare this to many other applications and platforms where you manually have to copy the files onto several servers and make sure that they’re in sync.

You can manually copy files into the SharePoint root folder and register the assemblies in the GAC (or build scripts that do it), but I don’t recommend that approach. Always use WSP packages to install your Features and solutions. If you manually add or edit files on the servers, your servers will eventually be out of sync and you’ll have to troubleshoot the problem. Deploying the Features and files using WSP files ensures that you can deploy your solutions in a consistent manner and keep all servers in the farm in sync.

A WSP file contains a solution manifest that defines the contents of the package. It’s this file that you’re editing when you use the Package designer in Visual Studio. There can only be one package per project. If you rename the WSP file with a .cab extension, you can easily browse its contents using Windows Explorer. The solution manifest is the file called manifest.xml. It contains general information about the solution and references all items such as the Feature manifest, assemblies, and global resources.

Each Feature in a package is located in a subfolder in the package file and contains the Feature manifest. The Feature manifest is an XML file named feature.xml that you edit in Visual Studio using the Feature designer. The designer allows you to modify only parts of the Feature manifest. For more advanced configurations, you have the option to edit a file called Feature. Template.xml or use the Edit options on the Manifest tab in the Feature designer. The advanced configurations made in the Feature.Template.xml are merged with the data from the Feature Designer during the packaging process in Visual Studio.

The WSP files are created when you run or debug your projects in SharePoint. You can manually invoke the packaging by selecting Build > Package. When the packaging is done, the project output folder contains the WSP file.

The solution manifest also contains information as to whether the assemblies should be registered in the GAC or copied to the Web Application bin directory. (See section 7.4 for more details.) Referenced assemblies needed for the solution are also defined here.

7.1.2. SharePoint Features

SharePoint Features consist of a Feature manifest file defining the Feature. Each Feature must be located in its own subfolder of the {SharePoint Root}/TEMPLATE/FEATURES folder. The Feature files from the solution packages are automatically extracted into those. The exception is the sandboxed solutions (which you’ll read in section 7.3). Features can be scoped at different levels, as shown in table 7.1, and they must be activated before you use them. Activation can be done from the web interface, using administrative commands, or automatically by SharePoint. When using Features with your Web Parts, the Features should always be scoped at the site collection level. This is because the Web Part Gallery is located at the site collection level.

Table 7.1. The Features are scoped to a specific level in SharePoint.

Level

Description

Farm (Farm) The Feature is used by the whole farm. Administration is done in Central Administration.
Web application (WebApplication) The Feature is used by a single web application. Administration is done in Central Administration.
Site collection (Site) The Feature is used by a site collection. Administration is done on the root website.
Website (Web) The Feature is used by a single website. Administration is done on the website.
Feature Activation

Activation of a Feature means that SharePoint reads the Feature manifest and goes through all the elements manifests within the Feature. These manifests are the actual content and actions that are applied to the scoped level. For instance, for a Web Part Feature the elements manifest contains a module that adds the Web Part controls description file to the Web Part Gallery. The elements manifests aren’t activated when you install the solution unless you’ve specified automatic activation, which is default for and only works on farm- or web application–scoped Features.

 

Note

When deploying solution packages from Visual Studio 2010, the Features will be activated by default. You can change this by editing the properties of the project and setting the Active Deployment Configuration option to No Activation.

 

Each Feature can also contain a Feature receiver. The Feature receiver is a class in an assembly that derives from the SPFeatureReceiver class and is used to programmatically perform actions on different events. This class has five event methods that are called on by SharePoint:

  • FeatureActivatedFired when the Feature is activated
  • FeatureDeactivatingFired when the Feature is deactivating
  • FeatureInstalledFired when the Feature is installed
  • FeatureUninstallingFired when the Feature is uninstalling
  • FeatureUpgradingFired when the Feature is upgraded

The runtime filter sample in chapter 5 used a Feature receiver to modify the web.config file for the web application in which the Feature was activated. Feature receivers are a great way to perform actions that you can’t do declaratively in the package, Feature, or elements manifests using the XML syntax. Feature receivers are compiled code and can do basically anything, and they can take advantage of the state and information in the currently targeted Feature scope.

You can add receivers to the Feature by right-clicking the feature in the Solution Explorer and selecting Add Event Receiver, as shown in figure 7.1. This will create a class under your Feature node that contains the receiver. By default, all methods are commented out and you need to uncomment those you’re going to implement for use.

Figure 7.1. Feature Event Receivers are added to a Feature by right-clicking the Feature in the Solution Explorer and selecting Add Event Receiver.

The Feature receivers have two methods that can be used when the solution is installed in the farm. These methods are fired after the installation of the Feature in the farm, and the methods are run on each server in the farm. The activation and deactivation methods are only run on one of the servers in the farm.

Feature Deactivation

When a Feature is deactivated, it fires the FeatureDeactivating method of the Feature receiver, but it doesn’t undo the actions completed by the module statements in an elements manifest. For instance, the Web Part isn’t removed from the Web Part Gallery. The reason that SharePoint doesn’t remove the .webpart file is that it’d then remove any customizations made to the file. If you want to make sure that the .webpart file is removed from the Web Part Gallery, you have to implement a Feature receiver. Listing 7.1 shows you how.

Listing 7.1. Deactivation code to remove Web Parts from the gallery
public override void FeatureDeactivating(
    SPFeatureReceiverProperties properties) {

    SPSite site = properties.Feature.Parent as SPSite;
    if(site != null) {
        SPList gallery = site.RootWeb.GetCatalog(
            SPListTemplateType.WebPartCatalog);

        SPListItem webPart = gallery.Items.Cast<SPListItem>()
            .FirstOrDefault(w => w.Name == "DeploymentWebPart.webpart");

        if (webPart != null) {
            webPart.Delete();
        }
    }
}

The Feature receiver has one parameter, properties, containing information about the current Feature. Using that parameter, you get the current site collection. Using the root web GetCatalog method, you retrieve the Web part Gallery. Because the Items collection is a nongeneric collection and you’re using LINQ, the collection is cast to IEnumerable. The first item matching the name of the Web Part controls description file defined in the elements.xml file is retrieved. If an item is found, it’s deleted from the gallery.

This method of removing items from the Web Part Gallery works fine if you’re interested only in removing the items that were added through the Feature. But because users can customize and add items to the Web Part Gallery, the filename might be changed or there might be multiple Web Parts defined in the gallery using the Web Part type. These Web Parts won’t be deleted by this Feature receiver. To ensure that all Web Part control description files in the Web Part Gallery that use the type of the Web Part defined in the Feature are removed, you need to change the deactivation method. Listing 7.2 shows the modified method. This method iterates through all items in the Web Part Gallery and checks the type used by the Web Part.

Listing 7.2. Improved deactivation code for removing Web Parts from the gallery

Instead of finding a Web Part control description file by name, this method iterates all items in the gallery . For each item, it retrieves the SPFile object so that a stream can be opened and finally loaded into an XDocument object. The XDocument class is defined in the System.Xml.Linq namespace. To get the Type defined in the item, a LINQ to XML query is used that looks for the type element and returns the name attribute. The value of the attribute is used to create a Type object. If this type is the same as the type of the Web Part class , the item is deleted.

This method allows for a more generic approach of removing Web Part control description files from the gallery and avoiding erroneous Web Part definitions. The Feature deactivator doesn’t remove any Web Parts used on pages in the site collection; it just removes them from the Web Part Gallery. The downside of using deactivation code that removes the .webpart files is that any customizations done to the Web Part Control Description files will be lost.

Feature Properties

In many situations you need to have configuration data for your solutions and Web Parts. For example, you might need database connection strings, web service endpoints, or other types of information. SharePoint 2010 has support for promoting properties from a Feature property bag, which is a container to store key/value properties, to a website, folder, or list item, but not on lists. This property bag can be used to set default values for your Web Part. There’s no support in Visual Studio for editing the property bags in a designer—you have to edit the Feature manifest XML file.

You add a property bag to a Feature by adding a new project item of the Empty Element type. You can add it to the project directly or to an existing SharePoint Project item such as a Web Part. The property bag is defined inside the Elements element as shown here:

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <PropertyBag
    ParentType="Web"
    RootWebOnly="True">
    <Property
      Name="FeedUrl"
      Type="string"
      Value="http://feeds2.feedburner.com/WictorWilen"/>
  </PropertyBag>
</Elements>

The property bag specifies that the properties should be promoted to the current SPWeb object and only on the root web. The property bag contains one or more properties, each of which has a name, a type, and a value.

When a Feature containing the element manifest is deployed and activated, it will add a new value to the property bag of the top-level web site of the site collection. The values of the property bag are retrieved using the AllProperties hash table object on the SPWeb object like this:

string url =
    SPContext.Current.Site.RootWeb.AllProperties["FeedUrl"] != null ?
        SPContext.Current.Site.RootWeb.AllProperties["FeedUrl"].ToString()
        : string.Empty;

Be cautious about what you store in these property bags. They can be accessed easily, even by sandboxed solutions. So don’t store any confidential information such as passwords.

7.1.3. Safe controls and the RequiresDesignerPermission attribute

All Web Parts and controls that will be used in an ASPX page of SharePoint must be registered as a safe control. This is a security rule that’s applied to each web application to avoid injections of malicious code.

Safe controls are registered in the web.config of each web application using the SafeControl element. The SafeControl entries are added to the web.config during deployment of a WSP package, and they’re defined in the package manifest. Each Web Part will have its own SafeControl entry, by default.

<SafeControl
    Assembly="WebPartsInAction.Ch7.SafeControls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9b0d982a432f9891"
    Namespace="WebPartsInAction.Ch7.SafeControls.TheWebPart"
    TypeName="*"
    Safe="True"
    SafeAgainstScript="False" />

The SafeControl entry defines the assembly and namespace in which the Web Part exists. The TypeName attribute contains an asterisk character (*) by default, which indicates that all types within the specified namespace are considered safe. The Safe attribute must be set to true; the only reason you’d set it to false is to exclude certain types or namespaces.

The SafeAgainstScript attribute is new in SharePoint 2010 and is by default set to false. This attribute is used to prevent cross-site scripting (XSS), which is the term used when malicious attackers try to inject client script code into a web page. When the SafeAgainstScript attribute is set to false, only users with the Designer permission can insert the Web Part into a page or edit its custom properties. More specifically, the users need the Add and Customize Pages site permission, which the Designer permission level by default contains.

Users without the Designer permission can’t edit custom properties and they won’t see them in the tool pane (unless they’re present in a custom Editor Part). If the property is accessible using an Editor Part, it’s up to the developer to make sure that the user can’t insert any malicious code. If a user without this permission level is trying to add a Web Part that isn’t marked as safe, then they’ll be presented with an error like the one in figure 7.2.

Figure 7.2. By default, users with only Contributor permissions aren’t allowed to add custom Web Parts that aren’t specifically marked as safe for scripting.

When the SafeAgainstScript attribute is set to true, users don’t need the Designer permission to add the Web Part to a page or change it properties. Visual Studio automatically adds the necessary safe control information to the solution package when adding new Web Part SPIs to the project. To change the value of the SafeAgainstScript tag, right-click the Web Part project item in the Visual Studio project and select Properties. In the Properties window, select the Safe Control Entries row and click the ellipsis button. This opens a dialog box where you can edit the SafeControl entry for this Web Part, as shown in figure 7.3. Change the value of the Safe Against Script property to True to mark the Web Part as safe against scripting. You can also use this dialog box to edit the other values in the SafeControl entry or add new ones.

Figure 7.3. Use the Safe Control Entries dialog box to modify the Safe Control elements of the package manifest. You can add and remove entries and edit their properties—for instance, you can mark a Web Part as Safe Against Script.

To enhance the security of Web Parts that are marked as Safe Against Script, you can add a specific attribute called RequiresDesignerPermission to those properties that you still want to disable for nondesigners, as shown here. The attribute is defined in the Microsoft.SharePoint.WebPartPages namespace and in this sample this namespace has the alias of SP:

[Personalizable(PersonalizationScope.Shared)]
[WebBrowsable(true)]
[SP.RequiresDesignerPermission(true)]
public string Text {
    get;
    set;
}

The RequiresDesignerPermission attribute is used to indicate that this property can only be edited by those with Designer permission, even if the Web Part is marked as Safe Against Script in the web.config file. It’s a good practice to use this attribute on all properties that accept text values and that are rendered in the Web Part to avoid cross-site scripting issues.

 

Tip

If you ever change the name of your Web Part (which you probably will do more than once), you also need to make sure that you update the Safe Control entry. Visual Studio doesn’t automatically update the class name or namespace of the Safe Control entry.

 

7.2. Deployment and activation

Once you’re done with your Web Parts and you’ve moved them into solution packages, you’ll want to run them in a nondevelopment environment. Then the process of deploying the solutions in the test, staging, or production environment begins. You no longer have the ease of Visual Studio doing all the work for you with deploying and activating Features.

SharePoint 2010 uses PowerShell for administration, and this is a great improvement over the previous STSADM command. PowerShell allows you to execute operations that are more advanced and scripting and automate the deployment process. This isn’t a book on PowerShell, but SharePoint 2010 requires you to have basic knowledge of it. If you want to get up to speed, I recommend Windows PowerShell in Action, 2nd Edition, by Bruce Payette (Manning, 2011). In this section, I’ll introduce the necessary SharePoint 2010 PowerShell commands, called cmdlets, used to add and deploy solutions and activate Features.

7.2.1. Solution deployment using PowerShell

When Visual Studio is used to build and debug Web Parts, the deployment process is automated. The process can be configured using the deployment configurations in Visual Studio. By default, Visual Studio retracts the old solution if it’s deployed before it adds the new solution and activates the Features when you start debugging. Once you’re done, it retracts the solution.

Visual Studio isn’t available on your production or test servers, so you have to do the deployment manually. The process can—and should be—scripted. You have a few options for making this deployment. You can use PowerShell or the STSADM command.

 

STSADM deployment

In SharePoint 2007, you used the STSADM command to add solutions. STSADM is a command-line tool used to configure and administer SharePoint. The tool is located in the {SharePoint Root}\bin folder. STSADM includes operations to perform administrative tasks in your SharePoint environment; some of these are available in Central Administration but most of them aren’t. SharePoint 2010 hasn’t removed the STSADM tool and it’s still included to support compatibility across product versions. You can use the STSADM command to deploy solutions and activate Features.

 

PowerShell is the way to go with SharePoint 2010. Learning PowerShell is crucial whether you’re an administrator or a developer. It can accomplish more tasks in more advanced ways than STSADM. When SharePoint 2010 is installed, it also installs a PowerShell snap-in for SharePoint. To use PowerShell for administering SharePoint, you can start either the SharePoint 2010 Management Shell or start PowerShell as normal and load the snap-in manually like this:

Add-PSSnapin Microsoft.SharePoint.PowerShell

Once the snap-in is loaded, you have access to all cmdlets in SharePoint. Deploying a solution requires that the WSP file is uploaded to the configuration database. The SharePoint cmdlet for uploading solutions is called Add-SPSolution. Installing a WSP is performed by invoking the cmdlet and passing the path to the WSP as an argument:

Add-SPSolution -Literalpath D:\install\WebPartsInAction.Ch7.Deployment.wsp

When the cmdlet is done, it returns the status of the operation, as shown in figure 7.4. The status includes the id of the solution and its deployment status. To retrieve a list of all installed solutions, use this command:

Get-SPSolution
Figure 7.4. PowerShell is the tool to use when you administer SharePoint. It can be used to view already installed solutions and deploy new ones.

 

PowerShell built-in help

Many cmdlets are available for SharePoint and they often have many parameters that you can take advantage of. PowerShell helps you write the commands—you can press the Tab key to access command completion and you can use the get-help cmdlet to search for or get help for a specific cmdlet.

Writing get-help *spfeature* will yield all commands related to Features and get-help Install-SPFeature -detailed will show you all the details about the Install-SPFeature cmdlet.

 

To remove a solution, you use the Remove-SPSolution cmdlet, but only solutions that aren’t deployed can be removed this way. If you need to remove solutions that are deployed, you must specify the -Force parameter. The -Force parameter can, for instance, be used when you have exceptions thrown in your Feature uninstall receiver methods.

Remove-SPSolution -Identity visualwebpartproject.wsp -Force

 

Note

There can be some confusion about the naming convention used in SharePoint. Deploying and installing is the same thing when it comes to solutions. Deploy is the term used in the interface (such as Central Administration), and install is the term used by PowerShell. The opposites are retract for the interface and uninstall in PowerShell. The same goes for Features. Features can be activated or deactivated in the web interface and enabled or disabled in PowerShell.

 

When the solution is uploaded into the farm, you must deploy it to use it. Deployment is accomplished using the Install-SPSolution cmdlet. This cmdlet takes a number of parameters. First, you need the name of your solution, which is the name of the WSP file. Because Web Parts are installed into a site collection, the name of the web application hosting the site collection is needed. The solution could be installed on all web applications by specifying the -AllWebApplications parameter, which includes Central Administration. But I recommend that you always specify which web applications you want to install your solutions in. For full-trust solutions, you must specify the -GACDeployment parameter so that installing the assembly in the GAC is allowed. Installation of a full-trust Web Part solution in a web application using a URL is done like this:

Install-SPSolution -Identity WebPartsInAction.Ch7.Deployment.wsp
    -WebApplication http://server/ -GACDeployment

This command will deploy the solution to the specified server and register the assembly in the GAC. The deployment can be verified using the Get-SPSolution cmdlet. To retract deployed solutions you use the Uninstall-SPSolution command like this:

Uninstall-SPSolution -Identity WebPartsInAction.Ch7.Deployment.wsp
    -WebApplication http://server -Confirm:$false

This command uninstalls the solution from the specified web application. The -Confirm:$false parameter is added to skip the confirmation prompt.

You can set the install and uninstall cmdlets to be executed at specific times. The examples presented so far are all performed immediately. Uninstallation and upgrades require that the application pools be recycled. This means that the web applications will be unavailable for a short period and current requests may be aborted. In scenarios when there are high availability requirements, all install and uninstall commands must be coordinated during specific support hours.

 

Note

All web applications in Microsoft Internet Information Services (IIS) need a process to execute in. These processes are called application pools and they can host one or more web applications. In SharePoint, the Central Administration website runs in its own application pool and the content web applications run in one or more application pools.

 

7.2.2. Feature activation and deactivation

When you’re deploying or debugging SharePoint solutions from Visual Studio, the Features are by default automatically activated. When the solutions are installed on staging or production servers, you need to activate the Features manually. Features can be activated in the user interface and, depending on its scope, in different places, as you can see in table 7.1. They can also be activated and managed using PowerShell. As a developer, you wouldn’t normally be the one responsible for deploying the solutions in the staging or production farms. But to make you aware of how administrators work with SharePoint and PowerShell, I’ll give you a quick introduction to Feature management in SharePoint. Also, I find it helpful as a developer and architect to create scripts as an aid to the administrators and for myself.

To list all installed Features, use the Get-SPFeature cmdlet. This command will give you the name, id, and scope of all installed Features in the farm. Most often, you have many Features installed so you can use PowerShell features to search the output from a cmdlet:

Get-SPFeature |
    Where-Object {$_.DisplayName -match 'WebPartsInAction*'} |
    Format-List DisplayName

This command will retrieve all Features installed and then filter out those that begin with WebPartsInAction. The result will be printed as a list using the Format-List command with only the display name instead of the default table format. The pipe character (|) sends the result of the previous command into the next one. Studying PowerShell and using features like this can be valuable. You can call Get-SPFeature with different scope parameters to show only the activated Features in that scope. To get the currently activated Features on a specific site collection, use this command:

Get-SPFeature -Site http://server/

A Feature is activated using the Enable-SPFeature cmdlet. This cmdlet takes the name of the Feature and the URL where it should be activated. For Web Part Features, the URL should be the URL to a site collection:

Enable-SPFeature -Identity WebPartsInAction.Ch7.Deployment_Deployment
    -Url http://server/sites/team1

Deactivating a Feature is similar to activating it. To deactivate a Feature, use the Disable-SPFeature cmdlet:

Disable-SPFeature -Identity WebPartsInAction.Ch7.Deployment_Deployment
    -Url http://server/sites/team1

PowerShell can take a while to learn, but it will be all worth it in the end. The advanced functions take the administration experience to a whole new level. Suppose you have a large farm with thousands of site collections. Activating or deactivating site collection–scoped Features can be tedious work. With PowerShell, you can do it with a single line of instructions. The following snippet lists all enabled site collection–scoped Features on all site collections in all web applications in the farm that have a specific name:

Get-SPWebApplication |
Get-SPSite |
ForEach-Object { Get-SPFeature -Site $_} |
Where-Object {$_.DisplayName -match "WebPartsInAction*"}

This PowerShell command retrieves all web applications in the farm, excluding Central Administration, and then pipes those to the next command using the pipe character (|). The next operation retrieves all the site collections from the piped web application. For each of the site collections it finds, the command retrieves all enabled Features. The $_ component is a local variable representing the current object in the pipeline. Only the ones matching the expression are returned. Note that Get-SPSite by default returns only 200 site collections, but you can change this limit by using the -Limit parameter. The command is split into several lines for easier reading, but you could write it on a single line.

 

Note

If you start building scripts for SharePoint using PowerShell, be aware that even in PowerShell you have to dispose of the objects. The SharePoint PowerShell snap-in has two commands to help you dispose of the objects correctly: Start-SPAssignment and Stop-SPAssignment. Use the built-in help to learn more about these cmdlets.

 

7.3. Sandboxed solutions

Sandboxed solutions were introduced in SharePoint 2010 to allow developers to create solutions and to make it easier to administer and control these solutions. Previous versions of SharePoint required that an administrator install the solutions, which often meant that applications had to be restarted. This, in turn, required a change ticket, which required someone to approve it, and so on. This process took time and often affected the creation of new solutions.

The sandbox in SharePoint allows site collection owners to create, deploy, and run their own solutions in a monitored and restricted sandbox. The resources and application failures in sandboxed solutions are measured, and a solution that exceeds its quota is automatically shut down. All this is done using the web interface, but adding a lot of solutions using the web interface isn’t the best way. The SharePoint Power-Shell extensions provide commands that automate these tasks.

When the limitations of the sandbox are too strict, SharePoint offers a way to build proxies that run in full trust and that can be used by sandboxed solutions. These proxies can’t be installed by the users; they must be installed as farm solutions and only administrators have control over them. You’re going to change our previous RSS Web Part into a sandbox solution. You’ll do this by removing the call in the Web Part to the external RSS feed and replacing it with a call to a full-trust proxy. The proxy that runs under full trust will then make the call to fetch the RSS feed and return it to the sandboxed Web Part.

7.3.1. What is sandboxing?

Sandboxed solutions, or user code solutions, are giving SharePoint a whole new level of extensibility. It allows site collection owners to build their own, download, or buy reusable solutions that can be used in the farm without involving administrators. These solutions can also be installed without incurring downtime for your web applications.

SharePoint Foundation has a service called Microsoft SharePoint Foundation Sandboxed Code Service in which all sandboxed solutions are executed. This process runs separately from the rest of SharePoint so any crashes or hiccups in the sandbox won’t affect SharePoint. SharePoint communicates with the sandbox by using a proxy, and vice versa. The code executing inside a sandbox is deployed to the database but never ends up in the file system. The sandboxed worker process has restricted security policies. For instance, you aren’t allowed to call web services or use custom database connections. You can add Web Parts, lists, workflows, and content types, and you can use event receivers in a sandboxed solution.

Sandboxed solutions are deployed into the Solution Gallery of a site collection. This also means that sandboxed solutions can only access information in the site collection to which it is deployed. To deploy a solution into the Solution Gallery, you go to Site Settings of the root web of the site collection and choose the gallery called Solutions. By selecting the Solutions tab in the Ribbon and clicking the Upload Solution button, you can upload a WSP package to the gallery. When the solution package is uploaded, it appears in the Solution Gallery; you can then select the solution and click Activate in the Ribbon to activate it (or Deactivate to deactivate the solution), as shown in figure 7.5. To be able to install sandboxed solutions, the user has to be a site collection owner, so not everyone is allowed to install sandboxed solutions.

Figure 7.5. The Solution Gallery in a site collection is used to manage the sandboxed solutions. Solutions can be activated, deactivated, and upgraded, and the current resource use is shown for the entire site collection and each solution.

SharePoint monitors all solutions running in the sandbox and logs counters such as CPU usage, thrown exceptions, and database queries. Each resource use is logged and assigned points, as shown in figure 7.5. When the total points from one or more solutions in one site collection reaches a certain threshold, the sandbox for the site collection will be shut down and the users won’t be able to use the solutions until the resource quota has been reset. The point quota is per day, so after 24 hours the solutions will be available once again. To prevent one single sandboxed solution from shutting down all the other solutions in the sandbox, it’s crucial that you create solutions that don’t throw unhandled exceptions, make unnecessary database calls, or perform other operations that count toward the resource quota.

7.3.2. Configuring the sandbox

The sandbox is controlled by the Sandboxed Code Service, described earlier. You start and stop this service by choosing Central Administration > System Settings > Manage Services on Server. To configure the service, choose Central Administration > System Settings > Manage User Solutions. Use the resulting configuration page to block user code solutions and specify load balancing for the Sandboxed Code Service.

The resource quotas for the sandboxed solutions are specified per site collection. To change the resource usage limit for a specific site collection, choose Central Administration > Application Management > Configure Quotas And Locks. Use the resulting page to set the maximum daily resource usage limit and the level of resource usage when a warning email should be sent to the site collection administrator. The quota templates used when creating site collections in SharePoint 2010 also contain the default values for the user code resource usage and the warning level.

PowerShell can be used to configure the Sandboxed Code Service. The Get-SPServiceInstance cmdlet retrieves the id and status of all SharePoint services:

Get-SPServiceInstance | format-list TypeName, Id, Status

This command lists all current service instances in the farm. You can start or stop using the Start-SPServiceInstance and Stop-SPServiceInstance, respectively. This command will stop the service with the specified id:

Stop-SPServiceInstance -Identity 6af4d5c3-6f8c-4f15-9a67-5b4c563bb0a6

7.3.3. Deploying and installing sandboxed solutions

You don’t have to use the web interface to deploy user code solutions. The SharePoint PowerShell snap-in contains cmdlets for working with user code solutions. When deploying a user code solution on several site collections, you should use Power-Shell scripting.

To list all installed user code solutions in a site collection, use the Get-SPUserSolution command. The command takes the URL to the site collection as a parameter:

Get-SPUserSolution -Site http://server/sites/site

This command only lists the sandboxed solutions within one site collection, but using command piping in PowerShell, you can combine a few SharePoint cmdlets to list all installed user code solutions in the farm:

Get-SPWebApplication | Get-SPSite | Get-SPUserSolution

The Get-SPWebApplication command will get all web applications, except Central Administration, and then pipe that to the Get-SPSite, which lists all site collections in the web application. Finally, all user code solutions for each site collection are printed.

Just as when installing farm solutions, the user code solutions have separate cmdlets. The Add-SPUserSolution is used to upload a WSP package to the Solutions Gallery and Remove-SPUserSolution removes it. Before removing any user code solutions, you need to deactivate them. Activation of user code solutions is done with Install-SPUserSolution and deactivation with Uninstall-SPUserSolution.

7.3.4. Full-trust proxies

Solutions built for the sandbox are limited due to the policy restrictions. If you try to access web services or databases from your sandbox solutions, you’ll be denied. You have three options if you need access to information available outside the sandbox from your user code solutions:

  • Install the solution as farm solution.
  • Use Business Connectivity Services (BCS) to access external data.
  • Create a full-trust proxy.

The first option is in many cases not an option at all (such as in hosted scenarios). If you don’t have access to the server or are unable to install farm solutions, your only option is to use BCS to connect to the external systems. But if you’re allowed to install farm solutions, full-trust proxies can be a good alternative. A full-trust proxy is an assembly that runs under full trust and is registered as a proxy with the Sandboxed Code Service. Sandboxed solutions can interact with the installed full-trust proxies and through them access external data. By making good decisions on what to install as full-trust proxies, you can minimize the amount of work spent on code reviews and server installation planning.

Let’s take the example of the RSS Web Part from chapter 5 and turn it into a sandboxed Web Part. The RSS Web Part reads an RSS feed from an URL; that action isn’t allowed in a user code solution, so you have to move that functionality to a full-trust proxy. First, create a new solution in Visual Studio based on the Empty SharePoint project template and choose to deploy it as a farm solution. A full-trust proxy contains proxy operations that are called by the sandboxed solutions. Create the proxy operations by adding a new class to the project that inherits from the SPProxyOperation class, available in the Microsoft.SharePoint.UserCode namespace. To pass arguments to the proxy operations, you need to create another class that inherits from the SPProxyOperationArgs class. Listing 7.3 shows the proxy operation arguments class.

Listing 7.3. Implementing the full-trust proxy operation arguments
[Serializable]
public class FeedOperationArgs : SPProxyOperationArgs {
    public FeedOperationArgs(string feedUri) {
        FeedUri = feedUri;
    }
    public string FeedUri {
        get;
        set;
    }
}

The proxy operation arguments class must be marked as serializable, and it inherits from the SPProxyOperationArgs class. A constructor is added that takes a string as an argument; that string is assigned to a public property. In this example, the string will represent the URL to the RSS feed that the Web Part is requesting.

The proxy operation will take an SPProxyOperationArgs object as an argument, which will be cast to the custom proxy operation argument. Listing 7.4 shows the implementation of the operation.

Listing 7.4. Implementation of the full-trust proxy operation
public class FeedOperation : SPProxyOperation {
    public override object Execute(SPProxyOperationArgs args) {
        if (args != null) {
            FeedOperationArgs feedArgs = args as FeedOperationArgs;
            if (feedArgs != null) {
                return XElement.Load(feedArgs.FeedUri).ToString();
            }
        }
        return null;
    }
}

The proxy operation inherits from the SPProxyOperation class and overrides the Execute method. This method is called by the sandboxed application using the proxy operation arguments. After casting the generic operation arguments into the custom arguments, the RSS is loaded using the XElement class, available in the System. Xml.Linq namespace; then the XML is returned as a string.

That completes our custom full-trust proxy; all you have to do now is register it with SharePoint. The best way is to add a new Feature to the project and set its scope to Farm level. Implement an event receiver for this Feature that will register the proxy when activated and unregister it when deactivated. This approach lets you easily manage the proxy from Central Administration. However, administrators can turn the proxy on or off as they like. To avoid that, you can hide the Feature and then make it available only for activation or deactivation using PowerShell or the STSADM command. In the event receiver, you have to implement the activation and deactivation methods, as shown in listing 7.5.

Listing 7.5. Registration and unregistration of the full-trust proxy

The FeatureActivated method gets the Type of the proxy operation class and retrieves the user code service. Using the service, it adds a new proxy operation type , which takes the full name of the assembly and class as arguments. Finally, the method updates the user code service to reflect the new proxy operation type. The FeatureDeactivating method is similar but instead of adding the proxy it removes it .

Once the Feature is activated, any user can create a sandboxed solution and access this full-trust proxy. To change the RSS Web Part, let’s use the code from listing 5.2 and remove the feed loading and replace it with a call to the proxy. The code will look like listing 7.6.

Listing 7.6. Invoking the full-trust proxy from a Web Part

To call the proxy, the SPUtility.ExecuteRegisteredProxyOperation method is called. This method takes the full assembly name and the class name of the proxy operation as arguments. These names must be exactly the same as the ones the proxy operation is registered with. The final argument is an object of the custom proxy operation argument. The method call will return an object that’s converted to a string, which is finally parsed by the XElement class before the controls are built to show the feed in the Web Part.

You deploy the sandboxed Web Part just as you would any other sandboxed solution. Once you add it to a page, it will show the specified feed. Using full-trust proxies allows you to leverage fully trusted code to sandboxed solutions developers. And administrators will be grateful that you’ve used a Feature to turn the proxy on or off.

7.4. Web application targeted solutions

So far in this book you’ve deployed Web Parts as full-trust solutions or into the very limited sandbox. Previous versions of SharePoint didn’t have a sandbox, and to deploy solutions under a more restricted security policy you deployed them into the web application’s bin folder as a partial trust assembly. This is still a valid option if you need to have a security level that’s not as strict as the sandboxed solution but not as fully trusted as farm solutions. Deploying partial trust solutions requires that you manually configure the security policy for your assembly using custom Code Access Security (CAS) policies. Although this approach can look like hard work at first, it’s a well-documented process.

7.4.1. Building solutions for web application deployment

Visual Studio 2010 by default doesn’t help you with building partially trusted solutions that are targeted for web application deployment. You should start a project by creating a farm solution in the SharePoint Configuration wizard. By default Visual Studio configures your assembly to be registered in the GAC. To change the assembly deployment target, select the project in the Solution Explorer and then press F4 to open the Properties window. This window contains a property called Assembly Deployment Target, as shown in figure 7.6. By default, it’s set to GlobalAssemblyCache, but to deploy it to the web application you must change the value to WebApplication. If you created a solution targeted for sandboxed deployment, you need to change the Sandboxed Solution property to False to enable the Assembly Deployment Target property.

Figure 7.6. Use the Properties window to change the deployment target between full trust and partial trust solutions.

The benefits of running Web Parts under partial trust are that doing so is more secure than running under full trust. Compared to sandboxed solutions (which have a fixed, limited security level), the security level of partial trust assemblies can be configured, which I’ll discuss later. To get access to more functionality in a sandbox, you need to build full-trust proxies; that means you must install two different solutions. Another benefit is that deploying assemblies to the bin folder of the web application doesn’t require that the application pool be recycled, thus reducing downtime. The disadvantage of partial trust solutions is that they require manual handling of CAS policies.

You can’t use Visual Web Parts in partially trusted solutions. The ASP.NET Framework’s LoadControl methods just don’t allow partial trust.

 

Note

The Visual Studio 2010 SharePoint Power Tools, available for download through the Extension Manager, allow you to create a Visual Web Part that works without loading the user control from the file system.

 

Changing the deployment target for the assembly will change the XML for the Package project item. The Assembly node has an attribute called DeploymentTarget that reflects the value of the project property. When the deployment target is changed to WebApplication, Visual Studio also adds the AllowPartiallyTrustedCallers attribute to the AssemblyInfo.cs file. This attribute allows partially trusted assemblies to call your assembly.

Now add a Web Part, not a Visual Web Part, to this project and add a simple Label control to it like this:

this.Controls.Add(new Label { Text = "I'm deployed to the bin - yeah!"});

Then press F5 to build, package, and deploy the solution. Once the deployment is done, add the Web Part to a page and see that it works. To verify that your assembly is deployed to the web application’s bin folder, open a Windows Explorer window and browse to c:\Windows\Assembly, which shows the contents of the GAC, and verify that your assembly isn’t there. Then open the folder of the IIS website—normally c:\inetpub\wwwroot\wss\VirtualDirectories\80\—and look for your assembly in the bin folder.

7.4.2. Code Access Security policies

The solution you just created now runs under the same security level as the web application. Farm solutions run under full trust, which means that any deployed code can do whatever it wants with your servers.

The security level of the web application is configured by the trust element in the web.config file and by custom Code Access Security (CAS) policies. By default, web.config defines the WSS_Minimal security level:

<trust level="WSS_Minimal" originUrl="" />

This is a default minimal level of security defined by SharePoint. The WSS_Minimal CAS policy is located in the {SharePoint Root}\Config\ and is called WSS_MinimalTrust.config. You shouldn’t change this file or the other policy files. If you need to manually change the settings, make a copy of them and edit the copy. The WSS_Minimal trust level restricts the code from accessing the SharePoint object model and resources such as the file system and database connections.

CAS policies can be quite hard to maintain, and it isn’t always obvious who’s responsible for creating CAS policies: the developer or the administrator of the farm. Most often the developer creates the CAS policies, because few SharePoint administrators know how to read and interpret CAS policies. This essentially makes the CAS policies useless. The whole purpose of using such policies is that the administrator who owns the SharePoint farm sets the security level of the solution.

 

Note

The Sandboxed Code Service uses a CAS policy to define actions permitted by the user code solutions. The policy file for the service is located in the {SharePoint Root}\Config folder and is called wss_usercode.config.

 

7.4.3. Custom CAS policies

To test the CAS policies, let’s change the Label control in our Web Part so that it prints the name of the current site. Change the Text property so that it looks like this:

this.Controls.Add(new Label {
    Text = "The name of this site is " + SPContext.Current.Web.Title }
);

This Label control will now output the name of the site, which is retrieved using the SPContext object. If you press F5 to deploy the solution and go back to the page where you previously added the Web Part (or create a new page with the Web Part), you’ll see the SharePoint Error message page. If you’ve disabled the custom error page (see chapter 8), a SecurityException is thrown, with the following exception details:

System.Security.SecurityException: Request for the permission of type
     'Microsoft.SharePoint.Security.SharePointPermission,
     Microsoft.SharePoint.Security, Version=14.0.0.0, Culture=neutral,
     PublicKeyToken=71e9bce111e9429c' failed.

This exception is thrown because you’re trying to use the SharePoint object model, which isn’t allowed by the default minimal CAS policy. To allow the solution to execute this code, you must add a custom CAS policy to the solution.

A custom CAS policy is defined in the solution manifest for the package. Once deployed it’s merged with the current policy of the web application. During installation, the trust level in web.config will be changed to WSS_Custom, which points to the merged policy file in {SharePoint Root}\Config. This custom policy file contains the default policy file and all merged custom CAS policies.

To add a custom policy to the solution, use the Package editor. In the Package designer, select the Manifest tab and then click Edit Options to bring up the editor. You can use the Package editor to add additional XML to the solution manifest, and the custom XML will be merged with the automatically generated XML and form the final solution manifest.

The custom CAS policy must contain the permission request that your application needs, in this example, that’s Microsoft.SharePoint.Security.SharePointPermission. But the policies aren’t inherited from the default policy, so you need to add all the policies needed to run the application. Listing 7.7 shows the custom CAS policy needed to run a Web Part that requires access to the SharePoint API. This XML is written into the Package Manifest template.

Listing 7.7. Custom CAS policies defined in the solution manifest

The custom CAS policy consists of policy item, which contains permission sets . The permission set is of the type NamedPermissionSet, and it’s given a description. For each requested permission, an IPermission element is added . The first granted permission is AspNetHostingPermission, which is used to gain minimal access to ASP.NET. The SecurityPermission is used with a set of flags to grant security permissions. The last permission grant is the one needed to access the SharePoint API. The ObjectModel attribute grants access to the application using the CAS policy to access SharePoint using the object model. Finally, the permission set is given to one or more assemblies, in this case the current Web Part assembly . The Visual Studio replaceable token is used here to insert the assembly filename.

Building custom CAS policies might be difficult at first because it involves using several different permission classes. I suggest that you start with a limited CAS policy, similar to the one discussed earlier, and then test the solution. The exceptions thrown usually give detailed information on which requested permission is required for the application to run.

 

Error in Visual Studio 2010 while deploying?

As of this writing, Visual Studio 2010 contains a bug that prohibits Visual Studio 2010 from deploying solutions with CAS policies. You’ll get an error like this: “Error occurred in deployment step ‘Add Solution’: Property set method not found.”

Fortunately there’s a workaround for this error detailed in Microsoft Knowledge Base article KB2022463 (http://support.microsoft.com/kb/2022463). This article contains instructions on configuring Visual Studio to accept CAS policies. In future service packs of Visual Studio, this bug will likely be fixed.

 

7.5. Upgrading solutions

Very few applications never need an update. The easy way to upgrade is to remove and reinstall the application, which is done in SharePoint by retracting and redeploying the solution. A better approach is to use the built-in functionality to upgrade a solution. (Previous versions of SharePoint could also do this, but the functionality was of limited use.)

In application life-cycle management, it’s good practice to use versioning of your code and assemblies. Due to annoying limitations and complicated workarounds, versioning of assemblies wasn’t often used in SharePoint projects prior to SharePoint 2010. As you’ll see in this section, this new version leverages native .NET features to make it easier to work with versioning in SharePoint.

This section also discusses how to handle updating of Web Parts when you’ve removed, added, or renamed properties.

7.5.1. How to upgrade

Upgrading solutions involves replacing the current solution with a new version. There are basically two ways to upgrade a solution:

  • Upgrade
  • Retract and redeploy

Depending on what has changed in your solution and the service level of your application, you can choose either approach. Retracting and redeploying a solution means that you completely remove the solution and its assemblies, Features, and files and once again apply them. SharePoint doesn’t remove any information from the content databases so it’s most often safe to use this method. On the other hand, because it removes files and Features, this method affects the state of the farm in a more serious manner than just upgrading the solution. You might also have to execute your Feature receivers once again, which could cause problems. Upgrading a solution is normally the quicker approach—and it works as long as you haven’t added any new Features to the solution (if that’s the case, you need to retract and redeploy).

You upgrade a solution using the PowerShell Update-SPSolution command. It’s similar to the Install-SPSolution cmdlet but requires that you specify the solution file to upgrade with:

Update-SPSolution
    -Identity WebPartsInAction.Ch7.Deployment.wsp
    -Literalpath D:\install\WebPartsInAction.Ch7.Deployment.wsp
    -GACDeployment

Sandboxed solutions can be upgraded using the web interface. You have two options to accomplish this. The first is to deactivate the solution, then upload the solution again and finally activate it. A better approach (which also supports the upgrade actions discussed later) is to rename the package using the Package designer and upload the new solution file. SharePoint will detect that it’s the same solution, unless you’ve changed the solution id. Then you can select the new item in the gallery and click Upgrade in the Ribbon to upgrade to the new solution.

For sandboxed solutions, there’s also a corresponding PowerShell command called Update-SPUserSolution. This command has to follow an Add-SPUserSolution command, which uploads the new WSP file with the new name to the Solution Gallery.

Update-SPUserSolution
    -Identity WebPartsInAction.Ch7.Deployment.wsp
    -ToSolution WebPartsInAction.Ch7.Deployment2.wsp
    -Site http://server

7.5.2. Upgrading Features

SharePoint 2010 has support for you to add custom code or apply new element manifests when upgrading a Feature. This support is useful if you need to upgrade any items that were provisioned in previous versions. For instance, you might want to add a new Web Part to the gallery when upgrading from one version to another.

The Feature manifest has a new element in SharePoint 2010 called Upgrade-Actions. This element can be used to specify actions to perform when upgrading from one version to another. Listing 7.8 shows a sample when upgrading from version 1.0.0.0 – 1.5.0.0 to the new version.

Listing 7.8. Using the UpgradeActions element

This upgrade action will apply to the specified version range . If the currently installed version is within that range, it will apply the specified element manifest . The upgrade will also invoke a custom upgrade action called RemoveOldWP with a parameter.

The custom upgrade action is passed to the Feature receiver of the Feature. Specifically the FeatureUpgrading method is called with the name of the upgrade action and the specified parameters. Listing 7.9 shows an implementation for the upgrade action in the previous listing. This function can be used if you’ve changed your Web Part implementation so that you need to remove the old definitions from the Web Part Gallery.

Listing 7.9. Using the FeatureUpgrading method

This upgrading action is quite similar to the FeatureDeactivating method in listing 7.2. The Feature upgrading method checks which upgrade action is passed to the method; if it’s the correct one, it proceeds. It retrieves all parameters having the key value equal to DeleteWebPart and iterates over those. For each iteration, it checks the Web Part Gallery items for a Web Part with the specified name and if it finds a Web Part, the method deletes it .

7.5.3. Assembly redirection

The .NET Framework uses assembly versioning to support running the same assembly but different versions side by side. It’s a good practice to give the assemblies a version number and increment the version number as the assembly is patched and evolved. Having a version number in combination with source control can help you when you’re troubleshooting your solutions.

The assembly version number is specified in the AssemblyInfo.cs file located under the Properties node in the Solution Explorer. The version is specified using an assembly attribute:

[assembly: AssemblyVersion("1.0.0.0")]

The version number is used for assembly full names in combination with the culture and public key token. Web Parts added to pages and stored in SharePoint store this full name of the Web Part class. If you change the version number of the assembly and replace the old assembly with your new one, then SharePoint won’t find the Web Part. Because previous versions of SharePoint lacked good support for changing the version number, most solutions never changed the version number.

The .NET Framework has support for a method called assembly redirection. This method redirects assemblies within a certain version span to another version. For example, all requests to an assembly of version 1.0.0.0 to 1.5.0.0 are redirected to version 2.0.0.0. This assembly redirection is specified in the configuration file of the application (with SharePoint, it’s web.config). You can do this manually by adding entries like these:

<runtime>
  <assemblyBinding>
    <dependentAssembly>
      <assemblyIdentity
        name="WebPartsInAction.Ch7.Upgrade"
        publicKeyToken="5bd2ee7eed22e9d1"
        culture="neutral" />
        <bindingRedirect
          oldVersion="1.0.0.0-1.5.0.0"
          newVersion="2.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
</runtime>

In the configuration file under the assemblyBinding node, a new dependent assembly is added. This contains an assembly identity, which specifies the name, public key token, and culture for the assembly. The redirection contains the source version range and the target version.

With SharePoint 2010, the ability to create assembly redirection has been incorporated into the solution manifest. That way, you avoid manual editing of the configuration file and thus avoid creating inconsistency between servers. When an assembly gets a new version and you want to use assembly redirection, you open the solution manifest in the Package editor and choose to edit the manifest template. From the preview windows of the packaged manifest, copy the Assemblies node into the manifest template editor; then delete everything beneath the Assembly element and add the redirect as follows:

<?xml version="1.0" encoding="utf-8"?>
<Solution xmlns="http://schemas.microsoft.com/sharepoint/">
  <Assemblies>
    <Assembly Location="WebPartsInAction.Ch7.Upgrade.dll">
      <BindingRedirects>
        <BindingRedirect OldVersion="1.0.0.0-1.5.0.0"/>
      </BindingRedirects>
    </Assembly>
  </Assemblies>
</Solution>

The Assembly element only needs to contain the Location attribute. The Deploy-mentTarget attribute has been deleted because it will be added automatically and will be present in the merged manifest. The BindingRedirect element specifies the version span from which the redirection should start. The destination version is retrieved from the current version of the assembly.

 

Note

You need to keep the old Safe Control entries in the web.config until you’re sure that all the old Web Part instances have been updated.

 

Even though redirection is a great way to use versioning on your assemblies, proceed with caution. You can’t make changes to the Web Part properties that make the old persisted values incompatible with the new version. If you change the type of a property, it can lead to unwanted results. Carefully plan your assembly redirections.

7.5.4. Upgrading Web Parts

If you make changes to your Web Part that make it incompatible with previous versions, such as renaming properties or changing how the property values are managed, you can’t just change the assembly. All property values of a Web Part in SharePoint are serialized into the content databases, and an upgraded Web Part could potentially break if the serialized state is inconsistent with what’s expected.

To upgrade a Web Part for which you’ve changed one or more properties, you have to implement the IVersioningPersonalizable interface. This interface contains a single method called Load, which is called whenever SharePoint detects one or more properties that exist in the database but not in the Web Part. Listing 7.10 shows a Web Part supporting the IVersioningPersonalizable interface and how it updates a property called OldProperty to the new property called NewProperty.

Listing 7.10. Upgrading a Web Part property

The Web Part derives from the IVersioningPersonalizable interface and implements the Load method. When the Load method is called, it stores the unknown properties into a local variable . When the OnInit method is called, it checks whether any unknown properties exist. If there are unknown properties, the method will loop through them and look for a property called OldProperty. If OldProperty is found, the method copies the value of that property into the new property called NewProperty . Once the new property is set, it calls the SetPersonalizationDirty method, which invalidates the Web Part and makes SharePoint save its personalization state.

 

Tip

If you’re upgrading a SharePoint Web Part to an ASP.NET Web Part, you can use the AfterDeserialize method of the SharePoint Web Part implementation to update properties. When a Web Part has been updated from a SharePoint Web Part to an ASP.NET Web Part, the first time it’s loaded it will be deserialized into a SharePoint Web Part and call the AfterDeserialize method. Then it will be serialized into the database as an ASP.NET Web Part.

 

7.6. Summary

This chapter covers deployment options and methods, and security considerations and implementations. It also introduced you to the world of PowerShell. I recommend that you learn PowerShell if you’re unfamiliar with it, because it will make your SharePoint administration experience much better. Scripting your deployment allows for better application life-cycle management and ensures that you do the same thing for all environments.

You also learned the implications of various deployment options. Running applications in full trust is the easiest way to build powerful applications but requires that you and your administrators be in total control of the code that’s being deployed. For better and detailed control of what the applications should be able to do, you can deploy them to the web application and use CAS policies to specify the security level. You and your power users can use sandboxed solutions to deploy applications; that way, your SharePoint farm is always safe and your applications are monitored. And you can extend the sandboxed solutions using full-trust proxies to leverage certain functionality to the user code solutions.

My recommendation is that you always start with sandboxed solutions. If you can do it in the sandbox, there’s no reason to play anywhere else.

So far in this book you’ve focused on building Web Parts and deploying them into SharePoint farms. In the next couple of chapters I’ll show you how to troubleshoot your Web Parts when the inevitable errors happen and how to get the most performance out of your Web Parts.