The Contoso.RI.Upgrade solution demonstrates how various site elements can be upgraded with new functionality and bug fixes.
The following are the elements that the upgrade changes and the elements that remain unchanged:
- Site columns. The upgrade adds a new site column named Instructor.
- Content types. The upgrade adds a new field named Instructor to the TrainingCourse content type.
- Web Parts. The upgrade adds a Web Part property named ShowTransactionGridLines to the TrainingBudgetWebPart. It removes a ShowLogin Web Part from the DirectReportsWebPart.
- Files and modules. The upgrade adds an image to the trainingdashboard.aspx and managerdashboard.aspx pages.
- Application pages. The upgrade adds an image to the registrationapproval.aspx page.
- User controls. The upgrade modifies the DirectReports.ascx user control to add an AlternatingItemStyle property to the DataList control.
- List item event handlers. Although the upgrade does not change any list item event handlers, it does include some special handling that is required to account for the new version number.
- Workflows. The upgrade modifies the workflow to contain a new custom code activity in the ifElseApprovalActivity to log to the workflow history list.
- Custom actions. The upgrade makes no changes to custom actions.
- List templates. The upgrade makes no changes to list templates.
- List definitions. The upgrade makes no changes to list definitions.
- List instances. The upgrade makes no changes to list instances.
The following sections include guidance on how to upgrade a SharePoint solution, using the Training Management application as an example. Note that not all aspects of the application are upgraded. These include custom actions, list templates, list definitions and list instances. There is also a brief discussion of issues that you should consider when you plan an upgrade to a SharePoint application that has been deployed to a production environment. For more information about this topic, see Deploying and Upgrading SharePoint Applications.
Note: |
| When upgrading an application, it is a common practice to increase the version number of the assemblies that make up the application. In the case of the Training Management application, the only assembly that was versioned was Contoso.TrainingManagement. Even though the Contoso.TrainingManagement.Common, Contoso.TrainingManagement.Repository, and Contoso.TrainingManagement.ServiceLocator assemblies are part of the SharePoint solution, the upgrade does not affect these assemblies enough to require a new assembly version. Cases where upgrades cause significant changes and the assemblies require a new version require careful planning. For example, in the Training Management application it is important to ensure that the registration approval workflow continues to function. This is because of the shared nature of those assemblies. SharePoint removes all assemblies in a SharePoint solution when the solution is retracted. This becomes an issue because the registration approval workflow also depends on the Contoso.TrainingManagement.Common, Contoso.TrainingManagement.Repository, and Contoso.TrainingManagement.ServiceLocator assemblies. |
Installing the Upgrade Solution
To install the upgrade SharePoint solution, follow the procedure in Installing the Upgrades. The upgrade installation replaces the originally deployed files with new versions. An alternative approach to the procedure is to use the STSADM command line tool. First use the stsadm–o retractsolution command to retract the original solution before installing the upgrade solution.
Note: |
| Another installation approach is to use the stsadm –o upgradesolution operation. This operation removes the files that are associated with the old version of the SharePoint solution and adds the files that are contained in the new version of the solution. This option also backs up the previous version of the SharePoint solution and stores it in the configuration database. This operation does not automatically install any new SharePoint features that are included in the solution or run any feature deactivation or activation code. You must manually install any new SharePoint features before they can be activated. Use the stsadm –o installfeature command to perform this operation. If you must deactivate or activate any SharePoint features, you must either use the stsadm –o deactivatefeature and stsadm –o activatefeature commands or use the SharePoint user interface. |
Site Columns
Site columns that are not customized reference the site column SharePoint feature element file. Adding new field definitions to the SharePoint feature element file causes any new activations of the SharePoint feature to provision the new site column. Existing activations of the SharePoint feature do not automatically receive the new field definitions. You must reactivate the SharePoint feature for this to occur. Do not remove site columns from a SharePoint feature element file because this can cause list items that use the site columns to break.
The upgrade SharePoint solution for the Training Management application adds a new site column named Instructor. The new site column is part of the ContosoTrainingManagementWeb SharePoint feature. You must reactivate this SharePoint feature to allow existing sites to receive the new site column.
The new site column is added by including the file Contoso.TrainingManagement\ContentTypes\TrainingCourseContentType\TrainingCourseInstructorField.xml in the Contoso.RI.Upgrade Visual Studio solution. The following code shows the new field.
<Elements Id="82fde2ad-e0ae-4889-b3c8-8ba72c822ac1" xmlns="http://schemas.microsoft.com/sharepoint/">
<Field ID="{65f64276-ef6f-4357-a33a-183e6e6a5863}" Type="Text" Name="TrainingCourseInstructor" DisplayName="Instructor" Hidden="False" Required="FALSE" Sealed="FALSE" DisplaceOnUpgrade="TRUE" />
</Elements>
Upgrading Content Types
When upgrading a content type that is defined by a ContentType feature element, you must consider whether the content type has been customized in the content database or whether it is found only in the file system of the Web front-end server. The two points to remember are the following:
- If a content type is not customized, sites reference the content type definition that is located in the file system of the Web front-end server.
- When a content type is enabled by a list, a copy of the content type is created in the list definition in the content database, even if no customization is involved.
When content types are located in both the Web front-end server and the content database, you cannot simply upgrade the content type by providing a new content type definition on the server. For example, when an upgrade adds a new field to a content type definition, any list instance that is enabled for that content type does not automatically receive the new field. You should consider the following guidelines:
- The recommended approach for adding new fields to a content type is to add them programmatically using the SharePoint object model.
- When a content type is programmatically upgraded, the SharePoint object model provides the option to upgrade child content types, including content types in list instances.
- Removing fields or updating the type of a field is not recommended. The recommended approach for removing a field is to make the field hidden.
- The recommended approach for updating the type of a field is to create a new field and set the old field to hidden.
- It is important to understand that if you follow these guidelines, you cannot have a centralized XML file that contains the content type definition after the upgrade. The content type XML should remain untouched after it is initially deployed and all upgrades should be done through code.
The upgrade SharePoint solution for the Training Management application contains code in the SiteFeatureReceiver class in the Contoso.TrainingManagement project to upgrade the Training Course content type with an Instructor field.
The following code is an example of how to add fields to a content type through the SharePoint object model.
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPSite site = null;
object parent = properties.Feature.Parent;
if (parent is SPWeb)
{
site = ((SPWeb)parent).Site;
}
else
{
site = (SPSite)parent;
}
this.UpdateSiteMap(site);
this.UpdateTrainingManagementContentType(site);
this.UpdateListItemEventReceivers(site);
}
private void UpdateTrainingManagementContentType(SPSite site)
{
this.EnsureFields(site, ContentTypes.TrainingCourse, new Guid(Fields.TrainingCourseInstructor));
}
private void EnsureFields(SPSite site, string contentTypeId, Guid fieldId)
{
SPContentTypeId spContentTypeId = new SPContentTypeId(contentTypeId);
SPContentType contentType = site.RootWeb.ContentTypes[spContentTypeId];
bool fieldLinkExists = false;
foreach (SPFieldLink fieldLink in contentType.FieldLinks)
{
if (fieldLink.Id == fieldId)
{
fieldLinkExists = true;
break;
}
}
if (!fieldLinkExists)
{
SPField fieldToAdd = site.RootWeb.Fields[fieldId];
contentType.FieldLinks.Add(new SPFieldLink(fieldToAdd));
contentType.Update(true);
}
}
This code queries the SharePoint object model for the SPField object that matches the given fieldID variable. It stores this in a local variable named fieldToAdd. The code then creates a new field link based on the field that is stored in the fieldToAdd variable. The code adds the link to the content type that is identified by the spContentTypeId variable.
Note: |
| Content type upgrades are performed through a SharePoint feature receiver. This means that you must activate the SharePoint feature. Most items that are defined in SharePoint feature element manifests must be reactivated. Components that are code in assemblies do not need reactivation. Files also do not need reactivation unless you are provisioning new Web Parts. |
Web Parts
Web Parts can be upgraded by providing a new version of the assembly that contains the Web Part code. If the assembly that contains the Web Part code contains a new assembly version number, you must perform the following additional steps to ensure that existing instances of the Web Part function correctly:
- Upgrade the SafeControl element in the Web.config file to reflect the new assembly version. For more information about the SafeControl element, see SafeControl Element (Solution) on MSDN.
- Upgrade any references to the Web Part definition in pages that contain Web Parts.
- Upgrade the .webpart file for the Web Part with the new assembly version to ensure that any new instances of the Web Part are properly imported.
In the upgrade SharePoint solution of the Training Management application, updates to the Web Part properties are made to the Direct Reports Web Part and the Training Budget Web Part. In the TrainingBudgetWebPart, a Web Part property named ShowTransactionGridLines is added. In the DirectReportsWebPart, the ShowLogin Web Part property is removed.
Files and Modules
If a file has not been customized, it can be upgraded by replacing the file with the new version in the Web front-end servers. Any changes to the file are automatically detected after a process cache refresh. However, this approach is not one that is recommended. When a new version of the file is copied over to the Web server, information about the file, such as its size and properties, may not correctly reflect the actual information about the file.
Additional consideration must be made when updating Web Part pages. Updates to Web Part pages can include list views and Web Parts. SharePoint always takes a non-destructive approach to upgrading Web Part pages. Any Web Part or list view that was provisioned through a SharePoint feature element is not removed or merged when the SharePoint feature is upgraded and reactivated. This may cause duplicate Web Parts or list views to appear after a SharePoint feature is reactivated.
One approach to correcting this behavior is to provide a new name for the file being upgraded and using the SPFile.MoveTo method. For example, the Training Management Reference Implementation contains a class named managerdashboard.aspx. To upgrade this file with additional Web Parts, you can change the name of managerdashboard.aspx to managerdashboard_v2.aspx. You can then write a feature receiver file that will move the managerdashboard_v2.aspx file to managerdashboard.aspx URL.
Note: |
| One word of caution is that this approach will cause you to lose all user customization to the file. |
This approach is only recommended for files where heavy customizations by users will not occur. If preservation of user customization is required, other approaches should be taken. For example, you can programmatically identify Web Parts and remove any duplicates. Alternatively, you can programmatically add the Web Parts to your Web Part page during feature activation. Neither of these approaches is demonstrated in the upgrade SharePoint solution. A file cannot be removed by removing it from the SharePoint feature. Any removal of files must be performed through the SharePoint object model's SPFile.Delete method.
The upgrade SharePoint solution of the Training Management application contains file changes and module changes. The upgraded application includes an image file that is displayed on several Web pages.
Figure 1 illustrates the original Training.aspx page.
Figure 1
Original training page
Figure 2 illustrates the upgraded page with the new image.
Figure 2
Training page with upgrade
Figure 3 illustrates the original management page.
Figure 3
Original management page
Figure 4 illustrates the upgraded management page with the new image.
Figure 4
Upgraded management page
Application Pages
Application pages are .aspx files that are stored in the virtual _layouts folder of the SharePoint Web front-end server. These pages are deployed once to the Web server and cannot be customized on a site-by-site basis. The pages are available across all sites within a server farm. To upgrade application pages, you can deploy a new version of the .aspx file to the Web server. The new page appears after a process cache refresh. These pages are relatively easy to upgrade because they cannot be customized by users and, therefore, are never stored in the content database. The upgrade to the Training Management application adds an image to the registrationapproval.aspx page. Figure 5 illustrates the original page.
Figure 5
Original registration approval page
Figure 6 illustrates the upgraded registration approval page with the new image.
Figure 6
Upgraded registration approval page
User Controls
User controls are upgraded by replacing the existing .ascx files with new versions of the .ascx files on the Web front-end server.
The upgrade to the Training Management application includes changes to the DirectReports.ascx user control in the Contoso.TrainingManagement.Web project to include an AlternatingItemStyle property to the DataList control.
List Item Event Handlers
Although the Training Management application upgrade does not include any changes to list item event handlers, there is still a new assembly version number.
Because the version number for the assembly has been upgraded but the old version information is still stored in the content database, you must do more than upgrade the assembly. The assembly information for event handlers is persisted in the content database for each list instance. Upgrades to the assembly must be performed through the SharePoint object model for each list instance. The following code is an example of how to upgrade the Assembly property of a SPEventReceiverDefinition instance which is found in the SiteFeatureReceiver.cs file in the Contoso.TrainingManagement project.
string newAssembly = "Contoso.TrainingManagement, Version=2.0.0.0, Culture=neutral, PublicKeyToken=9f4da00116c38ec5"; //our new assembly info
string newClass = "Contoso.TrainingManagement.TrainingCourseItemEventReceiver";
SPContentTypeId contentTypeId = new SPContentTypeId(ContentTypes.TrainingCourse); //our custom ctype
foreach ( SPWeb web in site.AllWebs )
{
using ( web )
{
for ( int i = 0; i < web.Lists.Count; i++ )
{
SPList list = web.Lists[i];
SPContentTypeId bestMatch = list.ContentTypes.BestMatch(contentTypeId);
if ( bestMatch.IsChildOf(contentTypeId) )
{
for ( int j = 0; j < list.EventReceivers.Count; j++ )
{
SPEventReceiverDefinition eventReceiverDefinition = list.EventReceivers[j];
if ( String.Compare(eventReceiverDefinition.Assembly, newAssembly, true) != 0 )
{
list.EventReceivers.Add( eventReceiverDefinition.Type, newAssembly, newClass );
eventReceiverDefinition.Delete();
list.Update();
}
}
}
}
}
}
This code iterates through all lists in a site collection that is enabled for the TrainingCourse content type and updates the SPEventReceiverDefinition property to use the new assembly information. For more information about the SPEventReceiverDefinition class, see SPEventReceiverDefinition Class (Microsoft.SharePoint) on MSDN.
Workflow
Workflows can be upgraded by making changes in the workflow code and redeploying the workflow assembly. For simple upgrades that do not require changes to the workflow properties or workflow activities, the version number for the assembly should remain the same and the new version of the workflow code should accommodate any old instances of the workflow. SharePoint serializes workflow instances and persists them to the content database. Any changes to the assembly can cause the workflow serialization engine to fail for the existing workflow instances.
In scenarios where significant changes to the workflow are required, including upgrades to the workflow properties, a best practice is to assign a new version number to the assembly. You should also provide a new version of the workflow template XML file. This approach also requires that a new workflow association be created.
By setting the workflow association of the old version of the workflow to No New Instances, you can prevent anymore workflow instances from being created with the old workflow. This allows you to introduce a new version of the workflow that runs side by side with the old version. The old workflow instances will complete, and the new workflow instances can use the upgraded code. One drawback to this solution is that if there are bugs in the old version of the workflow that are fixed in the new version, the old instances of the workflow still have the bugs in the code.
Note: |
| It is important that you consider upgrade scenarios when you initially create workflow solutions. Planning for upgrades early in the design and development phases prevents many difficulties during the maintenance phase. |
For more information, see Saving Workflow State and Upgrading Workflow Assemblies on MSDN.
The upgraded Training Management application includes changes to the registration approval workflow. The upgraded workflow contains new custom code activity in the ifElseApprovalActivity to log to the workflow history list. Figure 7 illustrates the original workflow.
Figure 7
Original workflow
Figure 8 illustrates the upgraded workflow with the logging activity.
Figure 8
Upgraded workflow
Custom Actions
Custom actions can be upgraded by providing an upgraded SharePoint feature element. To upgrade an existing custom action, make changes to the SharePoint feature element without changing the Id attribute of the CustomAction element. To remove a custom action, add a HideCustomAction element to a SharePoint feature element. The upgrade to the Training Management application does not include any changes to custom actions. For more information about the CustomAction element, see Custom Action Element (Custom Action) on MSDN. For more information about the HideCustomAction element, see HideCustomAction Element (Custom Action) on MSDN.
List Templates
List templates can be upgraded by providing a new version of the list template definition in a SharePoint feature. To upgrade certain properties of a list template that are persisted in the content database, such as OnQuickLaunch, DisplayName, Description, and Image, use the SharePoint object model. Any new list templates in a SharePoint feature are automatically available when the feature is reactivated. The upgrade to the Training Management application does not include any changes to list templates.
List Definitions
List definitions can be upgraded to include new fields or upgrades to non-customized views by upgrading the Schema.xml file in the SharePoint feature. Removing fields from the Schema.xml file is not a recommended practice. Modifying a field type of a field is also not recommended. Instead, create a new field to replace the old field. The upgrade to the Training Management application does not include any changes to list definitions.
List Instances
New list instances can be created by providing a new ListInstance element in a SharePoint feature. Reactivating the SharePoint feature that contains the ListInstance element causes new list instances to appear. Any existing list instances that are provisioned from modified or deleted ListInstance elements are not affected. Any upgrades to existing list instances should be performed through code. Also, forcing the reactivation of a SharePoint feature that contains upgraded ListInstance element with data items may cause duplicate list items. The upgrade to the Training Management application does not include any changes to list instances. For more information about the ListInstance element, see List Instance Element (List Instance) on MSDN.