Microsoft SharePoint Developer Documentation Team Blog
The Official Blog of the SharePoint Developer Documentation Team

  • Microsoft SharePoint Developer Documentation Team Blog

    We’ve Moved to the SharePoint Development Team Blog

    • 6 Comments

    Over the past few years, a number of MSDN blogs have been created that deal, at least in part, with SharePoint development, to the point where it’s sometimes challenging keeping up with them all. So, to make it easy for developers to make sure they’re getting all the latest technical information around developing SharePoint solutions, we’ve decided to combine those blogs into the one: the SharePoint Development Team Blog. Think of it as your one-stop shop for developer-centric SharePoint information, straight from the product teams and user assistance folk responsible for SharePoint Foundation, Server, SharePoint Online, and the SharePoint development tools in Visual Studio.

    Going forward, we’ll be posting the content that in the past you’d find on this blog to the SharePoint Development Team Blog. We’ve left this blog up, in maintenance mode, so that developers can still access the content we’ve published here. But be sure you subscribe to the new, consolidated blog for great content, including:

    ·       Detailed technical information on SharePoint development, such as walkthroughs and code samples, from the people who designed those product features and tools

    ·       Early, first-look versions of content being prepared for publication to MSDN

    ·       Cross-posts and pointers to SharePoint-centric developer content on other specialized blogs, such as Erika Ehrli’s, Eric White’s, or SharePoint in Pictures

    ·       Announcements of interest to SharePoint developers, such as content updates, service releases, or developer events.

    And pass the following easy-to-remember URL on to your SharePoint developer friends and colleagues:

    http://blogs.msdn.com/sharepointdev/

    Thanks for reading, and we hope to hear from you over at the SharePoint Development Team Blog!

  • Microsoft SharePoint Developer Documentation Team Blog

    New Visual Upgrade Article

    • 1 Comments

    Those of you who are interested in learning more about how to use Visual Upgrade in SharePoint 2010 should take a look at our recently published technical article, “Understanding Visual Upgrade,” by Ted Pattison. This and other upgrade resources are available at the SharePoint 2010 Upgrade Resource Center.

  • Microsoft SharePoint Developer Documentation Team Blog

    SharePoint Client Object Model Redistributable Released

    • 6 Comments

    Microsoft has released the SharePoint Foundation 2010 Client Object Model Redistributable. The assemblies for the .NET and Silverlight versions  of the SharePoint client object model are included. 

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

    The installer deploys these to the C:\Program Files\Common Files\Microsoft Shared\SharePoint Client folder of the development computer. (There are versions for 64-bit and x86 client computers.) In addition, resource assemblies are deployed to a subfolder named with the culture ID.

    The redistributable package must be installed on any client machine where your .NET client application is installed. You can either give users instructions on where to obtain it or you can include the redistributable in your installation package. This insures that the redistributable can participate in Windows Update and that each client computer has a legal copy of the assemblies. Some installation technologies enable you to call the redistributable's MSI file so the installation of the SharePoint .NET client assemblies and your application is seamless. SharePoint client assemblies obtained in other ways cannot be legally redistributed.

    You may distribute the assemblies for the Silverlight version along with a solution that targets them. They can be encased inside the Silverlight xap file. Alternatively, your solution can reference the Microsoft.SharePoint.Client.xap located on every SharePoint server in the SharePoint root: ...14\TEMPLATE\LAYOUTS\ClientBin folder.  It is also possible to cache the Silverlight assemblies. They are located in that same folder.

    Note that the third version of the SharePoint client object model, the JavaScript/JScript version, is defined in *.js files. These, of course, are downloaded to client computer when a SharePoint page that references them is opened. The default SharePoint master page references these files. Unless your solution includes a custom master page, you do not need to reference them in your own custom pages.

  • Microsoft SharePoint Developer Documentation Team Blog

    Application Lifecycle Management in Microsoft SharePoint 2010

    • 14 Comments

    Update, February 10, 2011: See the MSDN version of this article: Application Lifecycle Management in Microsoft SharePoint 2010.

    November 2010

    Applies to: Microsoft SharePoint Foundation 2010, Microsoft SharePoint Server 2010, Microsoft Visual Studio 2010 SharePoint Developer Tools, Microsoft Visual Studio 2010 Team Foundation Server and Microsoft SharePoint Designer 2010

    Summary: Learn how to plan and manage Application Lifecycle Management (ALM) in Microsoft SharePoint 2010 projects using Visual Studio 2010 and Microsoft SharePoint Designer 2010. Also learn what things should be considered when setting up team development environments, establishing upgrade management processes, and creating a standard development model.

    Introduction to Application Lifecycle Management in SharePoint 2010

    The Microsoft SharePoint 2010 development platform, which includes SharePoint Foundation 2010 (SPF2010) and SharePoint Server 2010 (SPS2010), contains many capabilities to help you develop, deploy, and update customizations and custom functionalities for your SharePoint sites. The activities that take advantage of these capabilities all fall under the category of Application Lifecycle Management (ALM).

    Key considerations when establishing ALM processes include not only the development and testing practices that you use before the initial deployment of a single customization, but also the processes that you must implement in order to manage updates and integrate customizations and custom functionality on an existing farm. This article discusses the capabilities and tools that you can use when implementing an ALM process on a SharePoint farm, and also specific concerns and considerations to take into account when you create and hone your ALM process for SharePoint development.

    This article assumes that each development team will develop a unique ALM process that fits its specific size and needs, so its guidance is necessarily broad. It also assumes, however, that regardless of the size of your team and the specific nature of your custom solutions, you will need to address similar sets of concerns and utilize capabilities and tools that are common to all SharePoint developers. The guidance in this article will help you as create a development model that exploits all the advantages of the SharePoint 2010 platform and addresses the needs of your organization.

    SharePoint Application Lifecycle Management: An Overview

    Figure 1 depicts a sample ALM process for a midsize or large SharePoint 2010 deployment. Obviously the process and required tasks depend on the project size.

    image

    These are the steps illustrated in figure 1:

    1. Initial requirements are collected and turned into tasks.

    2. Developers use Visual Studio 2010 Team Foundation Server or other tools to track the development progress and store custom source code.

    3. Since source code is stored in a centralized location, you can create automated builds for integration and unit testing purposes. You can also automate testing activities to increase the overall quality of the customizations.

    4. In larger projects, there could also be an additional build verification or user acceptance testing (UAT) farm, which is used by QA personnel to test and verify the builds in an environment that more closely resembles the production environment. Typically a build verification farm has multiple servers to ensure that custom solutions are deployed properly. Figure 2 illustrates a potential model for relating development integration and testing environments, build verification farms, and production environments. In this particular model, the pre-production or QA farm and the production farm switch places after each release. This model minimizes any downtime related to maintaining the environments.

    image

    5. After custom solutions have successfully undergone acceptance testing, you can continue to the pre-production or quality assurance environment.

    6 and 7. The pre-production environment should resemble the production environment as much as possible. This often means that the pre-production environment has the same patch level and configurations as the production environment. The objective of this environment is to ensure that your custom solutions will work in production. The production database can be copied to this environment occasionally, so that you can imitate the upgrade actions that will be performed in the production environment.

    8 and 9. After the customizations are verified in the pre-production environment, they are deployed either directly to production or to a production staging environment and then to production.

    10. The production environment is used by end users, who give feedback and ideas concerning the different functionalities. Issues and bugs are reported and tracked through established reporting and tracking processes.

    11. Feedback, bugs, and other issues in the production environment are turned into requirements, which are prioritized and turned into developer tasks. Figure 3 illustrates how multiple developer teams can work with and process bug reports and change requests received from end users of the production environment. The model in this figure also illustrates how development teams might also coordinate their solution packages. For example, the framework and the functionality development teams might follow separate versioning models that need to be coordinated as they track bugs and changes.

    image

    Another significant consideration in your ALM model is SharePoint Designer 2010. SharePoint 2010 is an excellent platform for no-code solutions, which can be made and deployed directly to the production environment by using SharePoint Designer 2010. These customizations are stored in the content database and are therefore not stored in your source code repository. Designer activities in general are another consideration. Will you be creating new page layouts directly within your production environment, or will you deploy them as part of your packaged solutions? There are advantages and disadvantages to both options.

    Your own ALM model depends completely on the custom solutions and the customizations that you plan to make, and on your own policies. Your ALM process does not have to be as complex as the one described in this section. However, you will need to establish a firm ALM model early in the process as you plan and create your development environment and before you start creating your custom solutions.

    The following section discusses specific tools and capabilities related to SharePoint 2010 development that you can use when considering how to create a model for SharePoint ALM that will work best for your development team.

    Solution Packages and the SharePoint Tools Continuum

    One major advantage of the SharePoint 2010 development platform is that it provides the ability to save sites as solution packages. A solution package is a deployable, reusable package stored in a .cab format file with a .wsp extension. You can create a solution package either by using the SharePoint 2010 user interface in the browser, SharePoint Designer 2010, or Microsoft Visual Studio 2010. In the browser and SharePoint Designer 2010 user interfaces, solution packages are also called templates. This flexibility allows you to create and design site structures in a browser and/or in SharePoint Designer and then import these customizations into Visual Studio 2010 for further development. Figure 4 illustrates this continuum.

    image

    When the customizations are complete, you can deploy your solution package to SharePoint and use it there. After modifying the existing site structure with a browser, you can start the cycle all over again by saving the updated site as a solution package.

    This tools continuum also enables you to use other tools. For example, you can design a workflow process in Microsoft Visio 2010 and then import it to SharePoint Designer 2010 and from there to Visual Studio 2010. For instructions on how to do this, see Create, import, and export SharePoint workflows in Visio.

    For more information on creating solution packages in SharePoint Designer 2010, see Save a SharePoint Site as a Template. For more information on creating solution packages in Visual Studio 2010, see Creating SharePoint Solution Packages.

    Using SharePoint Designer 2010 as a Development Tool

    SharePoint Designer 2010 differs from Microsoft SharePoint Designer 2007 in that its orientation has shifted from the page to features and functionality. The improved user interface provides greater flexibility for creating and designing different functionalities. It provides rich tooling for building complete, rich, reusable and process-centric applications. For more information about the new capabilities and features of SharePoint Designer 2010, see Getting Started with SharePoint Designer.

    You can also use SharePoint Designer 2010 to modify modular components developed with Visual Studio 2010. This means, for example, that you can create web parts and other controls with Visual Studio 2010, deploy them to a SharePoint farm, and then edit them in SharePoint Designer 2010.

    The primary target users for SharePoint Designer 2010 are IT personnel and information workers who can use this application to create customizations in a production environment. For this reason, you will need to decide on an ALM model for your particular environment that defines which kinds of customizations will follow the complete ALM development process and which customizations can be done by using SharePoint Designer 2010. Developers are secondary target users. They can use SharePoint Designer 2010 as a part of their development activities, especially during initial creation of customization packages and also for rapid development and prototyping. Your ALM process also needs to define where and how to fit SharePoint Designer 2010 into the broader development model.

    A key challenge of using SharePoint Designer 2010 is that when you use it to modify files, all of your changes are stored in the content database instead of the file system. For example, if you customize a master page for a specific site by using SharePoint Designer 2010 and then design and deploy new branding elements inside a solution package, the changes will not be available for the site with the customized master page, since that site is using the version of the master page that is stored in the content database.

    To minimize these kinds of challenges, SharePoint Designer 2010 contains new features that enable you to control usage of SharePoint Designer 2010 in a specific environment. You can apply these control settings at the web application or site collection level. If you disable some action at the web application level, that setting cannot be changed at the site collection level.

    SharePoint Designer 2010 makes the following settings available:

    • Allow site to be opened in SharePoint Designer 2010.
    • Allow customization of files.
    • Allow customization of master pages and layout pages.
    • Allow site collection administrators to see the site URL structure.

    These settings are ignored if you use the farm administration account.

    Since the primary purpose of SharePoint Designer 2010 is to customize content on an existing site, it does not support source code control. Pages that you customize by using SharePoint Designer 2010 are by default stored inside a versioned SharePoint library. This provides you with simple support for versioning, but not for full-featured source code control.

    Importing Solution Packages into Visual Studio 2010

    When you save a site as a solution package in the browser (from the Save as Template page in Site Settings), SharePoint 2010 stores the site as a .wsp file and places it in the Solutions Gallery of that site collection. You can then download the solution package from the Solutions Gallery and import it into Visual Studio 2010 by using the Import SharePoint Solution Package template, as illustrated in figure 5.

    image

    SharePoint 2010 solution packages contain a number of improvements that take advantage of new capabilities that are available in its feature framework. The following list contains some of the new feature elements that will be helpful to you in managing your development projects and upgrades (many of which are discussed later in this article).

    • SourceVersion for WebFeatures and SiteFeatures
    • WebTemplate feature element
    • PropertyBag feature element
    • $ListId:Lists
    • WorkflowAssociation Feature Element
    • CustomSchema attribute on ListInstance
    • Solution Dependencies

    After you have imported your project, you can start customizing it any way you like. Note that since this capability is based on the WebTemplate feature element, which is based on a corresponding site definition, the resulting solution package will contain definitions for everything within the site. See Web Templates for more information about creating and using web templates.

    Visual Studio 2010 supports source code control (as shown in figure 6), so you can store the source code for your customizations in a safe and secure central location and enable easy sharing of customizations among developers.

    image

    The precise manner in which your developers will access this source code and interact with each other depends on the structure of your team development environment. The next section of this article discusses key concerns and considerations that you should consider when you build a team development environment for SharePoint 2010.

    Team Development Environment for SharePoint 2010: An Overview

    As any ALM planning process, your SharePoint 2010 planning should include the following steps:

    1. Identify and create a process for initiating new projects.
    2. Identify and implement a versioning system for your source code and other deployed resources.
    3. Plan and implement version control policies.
    4. Identify and create a process for work item and defect tracking and reporting.
    5. Write documentation for your requirements and plans.
    6. Identify and create a process for automated builds and continuous integration.
    7. Standardize your development model for repeatability.

    Visual Studio 2010 Team Foundation Server (illustrated in figure 7) provides a good potential platform for many of these elements of your ALM model.

    image

    When you have established your model for team development, you will need to choose either a collection of tools or Microsoft Visual Studio 2010 Team Foundation Server to manage your development. Team Foundation Server provides direct integration into Visual Studio, and it can be used to manage your development process efficiently. It provides many capabilities, but your actual usage of it will depend on your projects.

    You can use the Team Foundation Server for the following activities.

    • Track work items and report the progress of your development. Team Foundation Server provides tools to create and modify work items that are delivered not only from Visual Studio 2010, but also from the Visual Studio 2010 web client.
    • Store all source code for your custom solutions.
    • Log bugs and defects.
    • Create, execute and manage your testing with comprehensive testing capabilities.
    • Enable continuous integration of your code by using the automated build capabilities.

    Visual Studio 2010 Team Foundation Server also provides a basic installation option that installs all required functionalities for source control and automated builds. These are typically the most heavily used capabilities of Team Foundation Server and this helps you set up your development environment more easily.

    Setting up a Team Development Environment for SharePoint 2010

    SharePoint 2010 must be installed on a development machine in order to take full advantage of its development capabilities. If you are developing only remote applications, such as solutions that use SharePoint web services, the client object model or REST, you could potentially develop solutions on a computer where SharePoint 2010 is not installed. Even in this case, however, your developers' productivity would suffer, since they would not be able to take advantage of the full debugging experience that comes with having SharePoint 2010 installed directly on the development computer.

    The design of your development environment will depend on the size and needs of your development team. Your choice of operating system will also have a significant impact on the overall design of your team development process. You have three main options for creating your development environments.

    You can run SharePoint directly on your computer's client operating system. This option is available only when you use the 64-bit version of Windows 7, Windows Vista Service Pack 1, or Windows Vista Service Pack 2.

    You can use the boot to VHD option, which means that you start your laptop using the operating system in VHD. This option is only available when you use Windows 7 as your primary operating system.

    You can use virtualization capabilities. If you choose to take advantage of virtualization capabilities, you have a choice of numerous options, but from an operational point of view, the option that is most likely to be the easiest to implement is a centralized virtualized environment that hosts each developer's individual development environment.

    The following sections take a closer look at these three options.

    SharePoint on a Client Operating System

    If you are using the 64-bit version of Windows 7, Windows Vista Service Pack 1, or Windows Vista Service Pack 2, you can install SharePoint Foundation or SharePoint Server. See Setting Up the Development Environment for SharePoint 2010 on Windows Vista, Windows 7, and Windows Server 2008 for more information on installing SharePoint 2010 on supported operating systems.

    Figure 8 illustrates how a computer running a client operating system would operate within a team development environment.

    image

    A benefit of this approach is that you can take full advantage of any existing hardware that you own that is running one of the targeted client operating systems. You can also take advantage of pre-existing configurations, domains, and enterprise resources that your enterprise supports. This could mean that little or no additional IT support would be required. Your developers would also face no delays (such as booting up a virtual machine, accessing an environment remotely, etc.) in accessing their development environments.

    If you take this approach, however, you will need to make sure that your developers have access to sufficient hardware resources. In any development environment, you should use a computer with an x64-capable CPU, and at least 2 gigabytes (GB) of RAM to install and run SharePoint Foundation; 4 GB of RAM is preferable for good performance. You should use a computer with 6 GB to 8 GB of RAM to install and run SharePoint Server.

    A disadvantage of this approach is that your environments will not be centrally managed, and it will be difficult to keep all of your project-dependent environmental requirements in sync. It might also be advisable to write batch files that start and stop some of the SharePoint-related services so that when your developers are not working with SharePoint, these services will not consume resources and degrade the performance of their computers.

    The lack of centralized maintenance could hurt developer productivity in other ways. For example, this might be an unwieldy approach if your team is working on a large SharePoint Online project that is developing custom solutions for multiple services (for example, the equivalents of http://intranet, http://mysite, http://teams, http://secure, http://search, http://partners, and http://www.internet.com) and deploying these solutions in multiple countries. If you are developing on a computer that is running a client operating system in a corporate domain, each development computer would have its own name (and each local domain name would be different, such as http://dev 1, http://dev2, etc.). If each developer is implementing custom functionalities for multiple services, you will have to use different port numbers to differentiate each service (for example, http://dev1 for http://intranet and http://dev1:81 for http://mysite ). If all of your developers are using the same Visual Studio 2010 projects, the project debugging URL will have to be changed manually whenever a developer takes the latest version of a project from your source code repository. This would create a manual step that could hurt developer productivity, and it would also diminish the efficiency of any scripts that you have written for setting up development environments, since the individual environments are not standardized. Some form of centralization with virtualization is preferable for large enterprise development projects.

    Windows 7 and Boot to VHD

    If you are using Windows 7, you can also create a virtual hard drive (VHD) out of an existing Windows Server 2008 image on which SharePoint is installed in Windows Hyper-V, and then configure Windows 7 with BDCEdit.exe so that it boots directly to the operating system on the VHD. See Deploy Windows on a Virtual Hard Disk with Native Boot and Boot from VHD in Win 7 to learn more about this kind of configuration.

    Figure 9 illustrates how a computer running Windows 7 and booting to VHD would operate within a team development environment.

    image

    An advantage of this approach is the flexibility of having multiple dedicated environments for an individual project, enabling you to isolate each development environment. Your developers will not accidently cross reference any artifacts within their projects, and they can create project-dependent environments.

    This option also comes with considerable hardware requirements, though, since you are directly utilizing the available hardware and resources on your computers.

    Centralized Virtualized Environments

    In a centralized virtualized environment, you host your development environments in one centralized location, and developers access these environments through remote connections. This means that you use Windows Hyper-V in the centralized location and copy a VHD for every developer as required. Each VHD is configured to be accessible from the corporate network, so that when it starts, it can be accessed using remote connections.

    Figure 10 illustrates how a centralized virtualized team development environment would operate.

    image

    An advantage of this approach is that the hardware requirements for individual developer computers are relatively light since the actual work happens in a centralized environment. Developers could even use computers with 1 GB of RAM as their clients and then connect remotely to the centralized location. You can also easily manage environments from one centralized location, making adjustments to them whenever necessary.

    Your centralized host will have significantly high hardware requirements, but developers can easily start and stop these environments. This enables you to use the hardware that you have allocated for your development environments more efficiently. Additionally, this approach provides a ready platform for more extensive testing environments for your custom code (such as multi-server farms).

    Once you have set up your team development environment, you can start taking advantage of the deployment and upgrade capabilities that come with the new solution packaging model in SharePoint 2010. The following sections describe how to take advantage of these new capabilities in your ALM model.

    Models for Solution Lifecycle Management in SharePoint 2010

    The SharePoint 2010 solution packaging model provides a number of useful features that will help you plan for deploying custom solutions and managing the upgrade process. You can implement assembly versioning by applying binding redirects in your web application configuration file. You can also apply versioning to your feature upgrades, and feature upgrade actions enable you to manage changes that will be necessary on your existing sites in order to accommodate feature upgrades. These upgrade actions can be handled declaratively or programmatically.

    The feature upgrade query object model enables you to create queries in your code that look for features on your existing sites that can be upgraded. You can use this object model to get relevant information about all of the features and feature versions that are deployed on your SharePoint 2010 sites. You can also configure in your solution manifest file the type of IIS recycling that you want to be performed during a solution upgrade.

    The following sections go into greater details about these capabilities and how you can use them.

    Assembly BindingRedirect

    The BindingRedirect feature element can be added to your web applications configuration file. It enables you to redirect from older versions of installed assemblies to newer versions. The XML configuration from the solution manifest file in figure 11 instructs SharePoint to add binding redirection rules to the web application configuration file. These rules forward any reference to version 1.0 of the assembly to version 2.0. This is required in your solution manifest file if you are upgrading a custom solution that uses assembly versioning and if there are existing instances of the solution and the assembly on your sites.

    image

    It is a best practice to use assembly versioning, since it gives you an easy way to track the versions of a solution that are deployed to your production environments.

    Feature Versioning

    The support for feature versioning in SharePoint 2010 provides a large number of capabilities that you can use when you are upgrading features. For example, you can use the SPFeature.Version property to determine which versions of a feature are deployed on your farm, and which features therefore need to be upgraded. See SPFeature.Version Property for a code sample that demonstrates how to do this.

    Feature versioning in SharePoint 2010 also allows you to define a value for the SPFeatureDependency.MinimumVersion property to handle feature dependencies. For example, you can use the MinimumVersion property to ensure that a particular version of a dependent feature is activated. Feature dependencies can be added or removed in each new version of a feature.

    The SharePoint 2010 feature framework has also enhanced the object model level to support feature versioning more easily. You can use the QueryFeatures method to retrieve a list of features, and you can specify both feature version and whether a feature needs an upgrade. The QueryFeatures method returns an instance of SPFeatureQueryResultCollection instance, which you can use to access all of the features that need to be updated. This method is available from multiple scopes, since it is available from the SPWebService, SPWebApplication, SPContentDatabase and SPSite classes. For more information about this overloaded method, see SPSite.QueryFeatures, SPWebService.QueryFeatures, SPWebApplication.QueryFeatures, and SPContentDatabase.QueryFeatures. For an overview of the feature upgrade object model, see Feature Upgrade Object Model.

    The following section summarizes many of the new upgrade actions that you can apply when you are upgrading from one version of a feature to another.

    Feature Upgrade Actions

    Upgrade actions are defined in the Feature.xml file. The SPFeatureReceiver class contains a FeatureUpgrading method, which you can use to define actions to perform during an upgrade. This method is called during feature upgrade when the feature's Feature.xml file contains one or more CustomUpgradeAction tags, as in the following example:

    <UpgradeActions>

    <CustomUpgradeAction Name="text">

    ...

    </CustomUpgradeAction>

    </UpgradeActions>

    Each custom upgrade action has a name, which can be used to differentiate the code that needs to be executed in the feature receiver. As in following example, you can parameterize custom action instances.

    image

    This example contains two CustomUpgradeAction elements, one named "example" and the other named "SecondAction." Both elements have different parameters, which are dependent on the code that you have written for the FeatureUpgrading event receiver. The following example demonstrates how you can use these upgrade actions and their parameters in your code.

    image

    You can have as many upgrade actions as you want, and you can apply them to version ranges. The following example illustrates how you can apply upgrade actions to version ranges of a feature.

    image

    The AddContentTypeField upgrade action can be used to define additional fields for an existing content type. It also provides the option of pushing these changes down to child instances, which is often the desired behavior. When you initially deploy a content type to a site collection, a definition for it is created at the site collection level. If that content type is used in any sub-site or list, a child instance of the content type will be created. To ensure that every instance of the specific content type is updated, you will need to set the PushDown attribute to true, as in the following example.

    image

    See Introduction to Content Types for more information about working with content types programmatically.

    The ApplyFeatureManifests upgrade action can be used to apply new artifacts to a SharePoint 2010 site without reactivating features. Just as you can add new elements to any new SharePoint elements.xml file, you can instruct SharePoint to apply content from a specific elements file to sites where a given feature is activated.

    You can use this upgrade action if you are upgrading an existing feature whose FeatureActivating event receiver performs actions that you do not want to execute again on sites where the feature is deployed. The following example demonstrates how to include this upgrade action in a feature.xml file.

    image

    An example of a use case for this upgrade action involves adding new .webpart files to a feature in a site collection. You can use the ApplyElementManifest upgrade action to add those files without reactivating the feature. Another example would involve page layouts, which contain initial web part instances that are defined in the file element structure of the feature element file. If you reactivate this feature, you will get duplicates of these web parts on each of the page layouts. In this case, you can use the ElementManifest element of the ApplyFeatureManifests upgrade action to add new page layouts to a site collection that uses the feature without reactivating the feature.

    The MapFile element enables you to map a URL request to an alternative URL. The following example demonstrates how to include this upgrade action in a feature.xml file.

    image

    This would be useful to you in a case where you need to deploy a new version of a page that has been customized by using SharePoint Designer 2010. The resulting customized page would be served from the content database. When you deploy the new version of the page, the new version will not appear because content for that page is coming from the database and not from the file system. You could work around this problem by using the MapFile element to redirect requests for the old version of the page to the newer version.

    It is important to note that the FeatureUpgrading method will be called for each feature instance that is to be updated. If you have 10 sites in your site collection and you update a web-scoped feature, the feature receiver will be called 10 times for each site context. See Feature.xml Changes for more information about how to use these new declarative feature elements.

    Upgrading Features: A High Level Walkthrough

    This section describes at a high level how you can put these feature versioning and upgrading capabilities to work. When you create a new version of a feature that has already been deployed on a large SharePoint farm, you need to consider two different scenarios: what happens when the feature is activated on a new site and what happens on sites where the feature already exists. When you add new content to the feature, you will first need to update all of the existing definitions and include instructions for upgrading the feature where it is already deployed.

    For example, say that you have developed a content type to which you need to add an additional custom site column. You need to add a new column called City to the previously deployed content type. First, you add a new element file to the feature. This element file defines the new site column and modifies the feature.xml to include the element file. The second step is to update the existing definition of the content type in the existing feature element file. This update will apply to all sites where the feature is newly deployed and activated. The third step is to define the required upgrade actions for the existing sites. In this case you will need to ensure that the newly added element file for the additional site column is deployed and that the new site column is associated with the existing content types. To achieve these two objectives you will add the ApplyFeatureManifests and the AddContentTypeField upgrade actions to your feature.xml file.

    When you deploy the new version of the feature to existing sites and upgrade it, the upgrade actions will be applied to sites one by one. If you have defined custom upgrade actions, the FeatureUpgrading method will be called as many times as there are instances of the feature activated in your site collection or farm.

    Figure 12 illustrates how the different components of this scenario fit together when you perform the upgrade.

    image

    Different sites might have different versions of a feature deployed on them. In this case you can create version ranges, which define specific actions to be performed when you are upgrading from one version to another. If a version range has not been defined, all upgrade actions will be applied during each upgrade.

    Figure 13 illustrates how different upgrade actions can be applied to version ranges.

    image

    In this example, if a given site is upgrading directly from version 1.0 to version 3.0, all configurations will be applied, since you have defined specific actions for upgrading from version 1.0 to version 2.0 and from 2.0 to version 3.0. You have also defined actions that will be applied regardless of feature version.

    Code Design Guidelines

    To provide more flexibility for your code, you should not place your upgrade code directly inside the FeatureUpgrading event receiver. Instead put the code in some centralized location and refer to it inside the event receiver, as illustrated in figure 14.

    image

    By placing your upgrade code inside a centralized utility class you increase both the reusability and the testability of your code, since you can perform the same actions in multiple locations. You should also try to design your custom upgrade actions as generically as possible, using parameters to make them applicable to specific upgrade scenarios.

    Upgrading Solutions

    If you are upgrading a farm (full-trust) solution, you will first have to deploy the new version of your solution package to a farm.

    Execute either of the following scripts from the command line to deploy updates to a SharePoint farm. The first example uses the stsadm command-line tool.

    stsadm -o upgradesolution -name solution.wsp -filename solution.wsp

    The second example uses the Update-SPSolution Windows Powershell cmdlet.

    Update-SPSolution -Identity contoso_solution.wsp -LiteralPath c:\contoso_solution_v2.wsp -GACDeployment

    After the new version is deployed, you can perform the actual upgrade which executes the upgrade actions that you have defined in your feature.xml files.

    A farm solution upgrade can be performed either farm-wide or at a more granular level by using the object model. A farm-wide upgrade is performed by using the psconfig command line tool, as in the following example.

    psconfig -cmd upgrade -inplace b2b

    Note that this tool causes a service break on the existing sites. During the upgrade, all feature instances throughout the farm for which newer versions are available will be upgraded. You can also perform upgrades for individual features at the site level by using the Upgrade method of the SPFeature class. This method will cause no service break on your farm, but you are responsible for managing the version upgrade from your code. See SPFeature.Upgrade for a code example that demonstrates how to use this method.

    Upgrading a sandboxed solution at the site collection level is much more straightforward. Simply upload the .wsp file that contains the upgraded features. If you have a previous version of a sandboxed solution in you solution gallery and you upload a newer version, an Upgrade option will become available in the user interface, as illustrated in figure 15.

    image

    After you select the Upgrade option and the upgrade is started, all features inside the sandbox solution will be upgraded.

    Conclusion

    This article has discussed some considerations and examples of ALM design, and it has also enumerated and described the most important capabilities and tools that you can integrate into the ALM processes that you choose to establish in your own enterprise. The SharePoint 2010 feature framework and solution packaging model provide a great deal of flexibility and power that you can put to work in your own ALM processes.

    Additional Resources

    For more information, see the following resources:

    · MSDN: Team-Based Development in Microsoft Office SharePoint Server 2007

    · MSDN: Understanding and Creating Customized and Uncustomized Files in Windows SharePoint Services 3.0

    · MSDN: Administrator and Developer Guide to Code Access Security in SharePoint Server 2007

    · MSDN: ASP.NET vs. SharePoint: How Development Differs

    · MSDN: Business Connectivity Services in SharePoint Foundation 2010

    · MSDN: Sandboxed Solutions

    · MSDN: Setting Up the Development Environment for SharePoint 2010 on Windows Vista, Windows 7 and Windows Server 2008

    · MSDN: Using Visual Studio for SharePoint Development

    · MSDN: Using SharePoint Designer for SharePoint Development

    · Microsoft Patters & Practices: SharePoint Guidance

    · SharePoint Team Blog: Managing Upgrades on Sandbox Solutions

  • Microsoft SharePoint Developer Documentation Team Blog

    Activity Event Sample on Code Gallery: How to Publish Events with a Timer Job

    • 0 Comments

    The SharePoint Server 2010 social data object model enables you to create your own activity types and publish activity events in custom applications. One important limitation, however, is that only users who have User Profile Service Application administrative privileges can publish activity events. You cannot, therefore, create a custom application that publishes activity events directly after a given user takes an action, unless you know for sure that the user will always be a User Profile Service Application administrator. This limitation helps keep unwanted items from overwhelming users’ activity feeds, but it also requires developers to plan ahead, work with administrators, and design custom applications that work around this limitation.

    One way to work around the limitation is to store information about activity events in a hidden list. You can then create a timer job that runs at times and frequencies that you and your administrators establish beforehand in order to balance performance considerations with user experience concerns, such as the timeliness of the information in the activity feeds. This timer job would use information in the hidden list to create activity events and then publish these events by using the multicasting methods in the social data object model. If the publication succeeds, the timer job would then clear the list. Because this hidden list might become large, you would need to follow the best practices guidance in the Handling Large Folders and Lists topic.

    The Microsoft SharePoint Server 2010: Activity Events for Document Libraries sample on Code Gallery provides a prototype for how this sort of design can work. It publishes an activity event to the activity feeds of a user’s colleagues whenever that user adds a document to a document library. The solution creates the new activity type to which the published activity events belong, along with the hidden list on feature activation.

    Take a look at the sample and provide feedback on it by commenting on this post or on the Code Gallery resource itself. In addition to performance considerations, one potential drawback of this approach is that there will be a short interval between the publication of activity events and the clearing of the hidden list, which means that someone could potentially add a document within that interval, the list would be cleared, and the event would not get published. Let us know if you notice other drawbacks, or if you can think of ways to improve upon this design.

  • Microsoft SharePoint Developer Documentation Team Blog

    Introducing the Published Intranet Solution Center

    • 0 Comments

    The SharePoint 2010 Published Intranet Solution Center has just launched on Technet. A Technet solution center is a blueprint that outlines the tasks and people who need to be involved, and the steps that need to be taken when you implement a certain kind of custom solution in your enterprise. It covers the entire lifecycle of a SharePoint 2010 custom solution – from initial evaluation through planning and development, deployment, and on to operations and maintenance. Although it is published on Technet, it addresses all of the audiences, including developers, who need to be involved with the solution.

    See Samantha Robertson's post for a fuller description of the solution center concept, and go to the Published Intranet Solution Center itself to take a look.

  • Microsoft SharePoint Developer Documentation Team Blog

    Quick Tip: Find the Four-Part Name for an Assembly

    • 7 Comments

    When developing for SharePoint, you sometimes need to find the four-part name for an assembly. You can do this inside of Visual Studio 2010 using PowerShell. It’s pretty straight-forward.

    1. In the Tools menu of Visual Studio, click External Tools.
      Tools Menu
    2. In the dialog, click Add to get a new tool.
      External Tools Menu
    3. Now, configure the tool with the following options:
      Title: Get Four-Part Name
      Command: powershell.exe
      Arguments: –command "[System.Reflection.AssemblyName]::GetAssemblyName(\"$(TargetPath)\").FullName
      Use Output window: Checked
      image
    4. Click OK to dismiss the window.

    Now, you can go into the Tools menu to see your tool. If you click it, it will print out the four-part name including the public key token in your Output window.

    image

  • Microsoft SharePoint Developer Documentation Team Blog

    New Visual "How to" about Creating Custom Field Types

    • 0 Comments

    Ted Pattison has produced a new video showing how to create a custom field type in SharePoint.

    For a link to the video and the written summary, see Creating Custom SharePoint 2010 Field Types.

  • Microsoft SharePoint Developer Documentation Team Blog

    New Visual "How to" about Creating Multicolumn Field Types

    • 0 Comments

    Ted Pattison has produced a new visual showing how to create a multicolumn field type in SharePoint.

    For a link to the video and the written summary, see Creating Multicolumn SharePoint 2010 Field Types.

  • Microsoft SharePoint Developer Documentation Team Blog

    New Visual "How to" about Extending the SharePoint Tools in Visual Studio

    • 0 Comments

    Ted Pattison has produced a visual "How to" about how to extend the SharePoint tools in Visual Studio 2010.

    For a link to the video and the written summary go to Creating Custom Extensions for SharePoint 2010 Development Tools in Visual Studio 2010.

  • Microsoft SharePoint Developer Documentation Team Blog

    How to install Sandboxed Solution with Powershell (SharePoint Management Shell)

    • 0 Comments

    Farm solutions can be installed with SharePoint Management Shell (PowerShell), but did you know that sandboxed solutions can be too?

    The cmdlets have almost the same name as the corresponding cmdlets for farm solutions, the difference being that "User" is inserted after the "SP".

    To upload a sandboxed solution to a site collection's Solution Gallery with PowerShell, use the cmdlet Add-SPUserSolution. At a minimum, you need to identify the path to the solution package (wsp file) and the target site collection by using the LiteralPath and Site parameters. Example:

    Add-SPUserSolution -LiteralPath c:\CandidateSandboxedSolutions\MySandboxedSolution.wsp -Site http://MyServer/sites/Contoso

    Now, of course, you need to deploy the solution, except that when we are talking about sandboxed solutions, this step is called "activation" instead of "deployment".  But, between you and me, it is the same thing. (And activating a sandboxed solution is not conceptually the same thing as activating a SharePoint Feature.) To deploy the solution, use the Install-SPUserSoluton cmdlet. At a minimum, you need to identify the solution that you want to deploy and the site collection by using the Identity and Site parameters. Example:

    Install-SPUserSolution -Identity MySandboxedSolution.wsp -Site http://MyServer/sites/Contoso

    You can reverse the latter step with the Uninstall-SPUserSolution cmdlet with the same two mandatory parameters. You can reverse the first step with the Remove-SPUserSolution cmdlet. It also requires the Identity and Site parameters.

    There is also an Update-SPUserSolution cmdlet which is used, of course, to update a solution that has already been "activated" (that is, deployed). The syntax is the same as the Install-SPUserSolution except that you use the Identity parameter to identify the old solution and you use ToSolution parameter to identify the new replacement solution. You must first use the Add-SPUserSolution to upload the new version of the solution to the Solution Gallery. Example:

     Add-SPUserSolution -LiteralPath c:\CandidateSandboxedSolutions\MyImprovedSandboxedSolution.wsp -Site http://MyServer/sites/Contoso

    Update-SPUserSolution -Identity MySandboxedSolution.wsp -Site http://MyServer/sites/Contoso -ToSolution MyImprovedSandboxedSolution.wsp

    There are additional, optional, parameters for all of these cmdlets. For help on any of them, use the Get-Help cmdlet followed by the name of the cmdlet and the "full" parameter. Example:

    Get-Help Add-SPUserSolution -full

  • Microsoft SharePoint Developer Documentation Team Blog

    Overview of SharePoint Online Development Now Live

    • 0 Comments

    So, last week we published the SharePoint Online Developer Resource Center, to serve as a one-stop shop that pulls together all the resources a developer needs to get up to speed on developing for SharePoint Online. But what if, instead of the numerous in-depth resources we’ve included on the center, you want to get an overview of developer options for SharePoint Online in a single technical article?

    Then have we got something for you:

    SharePoint Online: An Overview for Developers

    (And seriously, would I have asked the question if we didn’t have something ready for you?)

    We’ll be rolling out detailed guidance for developing SharePoint Online solutions in the weeks and months ahead, but this article should enable you to familiarize yourself with the broad strokes of developing for SharePoint in the cloud. Use the article to learn about the developer features that are coming to SharePoint Online, strategies and patterns for successfully developing on SharePoint Online, and find links to additional resources for developers to deepen their knowledge of these extensibility features

    I’d be very interested in what you think of the article, and what questions you have about developing for SharePoint Online after reading it and visiting the Resource Center. So please leave a rating and comment on the article, or leave a comment here about what kind of coverage you’d like to see around SharePoint Online development.

  • Microsoft SharePoint Developer Documentation Team Blog

    SharePoint Online Developer Resource Center Now Live

    • 0 Comments

    As you’ve not doubt heard by now, today Microsoft announced Microsoft Office 365, our next generation in cloud productivity suite that brings together Microsoft Office, SharePoint Online, Exchange Online and Lync Online in an always-up-to-date cloud service. As part of today’s news, Microsoft is also opening a limited beta program for Office 365 in 13 countries and regions. (To learn more about Office 365 in general, or the beta program, visit www.office365.com.)

    To support the Office 365 beta program, and to give developers their first look at the extensibility story for this new version of SharePoint Online, we’ve launched the SharePoint Online Developer Resource Center on MSDN.

    Whether you are participating in the beta program, are planning on creating solutions for SharePoint Online down the road, or are just curious to see what all the talk is about, I encourage you to check out the resource center. We created the resource center to serve as a one-stop shop that pulls together all the resources a developer needs to get up to speed on developing for SharePoint Online, no matter what their skill set and previous experience with SharePoint. This includes articles, blogs, videos, walkthroughs, and in-depth training from across Microsoft web properties such as MSDN, Channel 9, and patterns & practices. We’ve selected the resources you need to ramp up on the developer features available in this new version of SharePoint Online, such as:

    ·       SharePoint Designer customization

    ·       Sandboxed solutions

    ·       SharePoint managed, Silverlight, and ECMAScript client object models

    ·       SharePoint .NET and REST Web services

    ·       Excel, InfoPath Forms, Visio, and Access Services

    We plan on keeping the resource center up-to-date as new materials come online (either from Microsoft sources, or the Web in general), so be sure to bookmark the page and check back often. And, as always, if there’s something you want to see in the resource center and don’t, let us know.

  • Microsoft SharePoint Developer Documentation Team Blog

    Where are Assemblies in Sandboxed Solutions Deployed?

    • 5 Comments

    Because sandboxed solutions cannot deploy files to a server's file system, there is some puzzlement over where the assemblies in sandboxed solutions are deployed and persisted.  The situation is not helped by the fact that the package manifest of a sandboxed solution implies that such assemblies are deployed to the GAC as the following screenshot shows. This is not the case.

    The assemblies in a sandboxed solution are included in the solution's package (wsp file) and the package is deployed to the site collection's Solutions Gallery. When a sandboxed solution is accessed for the first time, such as when a user navigates to a page containing a Web Part from a sandboxed solution, any assemblies in the solution are unpacked from the wsp and copied to the file system of the server that is handling the sandbox request. The location is C:\ProgramData\Microsoft\SharePoint\UCCache. The server that handles the sandbox request is not necessarily the front-end web server that is handling the initial HTTP request: the User Code Host Service can be run on back end application servers in the farm instead. Since the sandboxed user process (SPUCWorkerProcess.exe) cannot copy anything to the file system, the copying is done by the User Code Host Service.

    The assemblies do not stay in the file cache perpetually. When the user session that accessed the assemblies ends, the assemblies stay in the cache for only a short time and they may be reloaded from there if another user session assesses them. Eventually, if they are not accessed, they are removed in accordance with a proprietary algorithm that takes into account how busy the server is and how much time has gone by since the assemblies were last accessed. If the sandboxed solution is used after that time, the assemblies unpacked again and copied to the UCCache.

    Administrators, developers, and third-party code should not add, remove, or load anything from the UCCache. It should only be accessed by the SharePoint infrastructure.

    Rick - MSFT

  • Microsoft SharePoint Developer Documentation Team Blog

    Getting Started with the SharePoint Developers Tools in Visual Studio 2010

    • 0 Comments

    You can use many resources to get started developing SharePoint solutions. In addition to the MSDN Library documentation for SharePoint SDK and the SharePoint Developer Tools in Visual Studio, you can access articles and videos that are published in the Technical Articles and Visual How Tos nodes. In addition to the documentation, technical articles, and visual how-tos, you can also read Book Excerpts and Quick Notes.

    For example, you can watch this visual how-to video that explains how to create, test, and debug SharePoint 2010 projects by using Visual Studio. The accompanying walkthrough is at http://msdn.microsoft.com/en-us/library/gg131919.aspx.

    image

    There are additional videos about SharePoint that appear on the Related Videos tab, as well as the Up Next tab.

    Related MSDN Library documentation include the following topics:

    Mary Lee, Programming Writer.

  • Microsoft SharePoint Developer Documentation Team Blog

    Check out SharePoint in Pictures

    • 0 Comments

    We’ve launched a new blog called SharePoint in Pictures. It is a blog that will feature diagrams of SharePoint as a development platform. Check out the new blog at http://blogs.msdn.com/b/sharepointpictures/ and give us your feedback!

  • Microsoft SharePoint Developer Documentation Team Blog

    Updated SharePoint 2010 SDK Now Available for Download

    • 0 Comments

    (Cross-posted from Randall's blog.)

    The SharePoint 2010 Software Development Kit (SDK) has been updated! Get it here: Download from the Microsoft Download Center

    What’s New in this SDK Update

    We are excited to announce the latest quarterly update of the SDK for SharePoint Foundation 2010 and SharePoint Server 2010. This free update replaces previous 2010 versions of the SDK and includes the following:

    • New code samples:  Silverlight List Viewer, plus new samples in Business Connectivity Services (BCS), Enterprise Content Management (ECM), and User Profiles and Social Data
    • Updated documentation, including: new and updated How To, reference , and conceptual content
    • Updated IntelliSense XML files for tooltips and auto-complete in Visual Studio

    Here are two MSDN topics listing new and updated content and code samples in the AUG2010 version of the SDK (14.0.4763.1031):

    A complete listing and description of the 44 code samples currently available in the SDK can be found here on MSDN Code Gallery: http://code.msdn.microsoft.com/sp2010sdk.

    Change History Tables

    Wondering what has changed in the SDK?  You can do a quick search in the compiled HTML Help (.chm) files for the phrase “content update” (include the quotes) to see all the changed topics.  We also publish the “Updated” date at the top of each article.  Check out an example here: http://msdn.microsoft.com/en-us/library/ff623048.aspx.

    Working with Help in Visual Studio (MSDN and Local)

    This update also coincides with republish of the SDK in the MSDN Library, in addition to offline Visual Studio Help for SharePoint.  Yes, that’s right—now you can get context-sensitive Help directly from your code by pressing F1 in Visual Studio. 

    F1 Help and Working Offline

    The MSDN Library is always the most up-to-date source of information, and Visual Studio uses online Help as its primary source by default when you press F1. If you need to work offline, however, you can first download Help content from MSDN using the Visual Studio 2010 Help Library Manager (Help > Manage Help Settings).  Here’s how:

    1. Click Check for updates online.
      You may need to change your settings to I want to use local help.  You can find this under Choose online or local help in Help Library Manager.
    2. Scroll down to SharePoint 2010 SDK, click Add, and then click Update.

    image

    IntelliSense XML Files Update

    The latest drop of the SDK also updates all the IntelliSense XML files for SharePoint Foundation 2010 and SharePoint Server 2010.  Please refer to the Readme.txt file for installation instructions.  The readme.txt files is in the C:\Program Files (x86)\Microsoft SDKs\SharePoint 2010\Intellisense once the SDK is installed.

    You will get tooltips, updated descriptions, and auto-complete as you type code in the Visual Studio 2010 IDE once the IntelliSense XML files are updated.  Visual Studio 2010 and SharePoint 2010 must be installed on the computer you are installing the IntelliSense XML files on; the IntelliSense files only work in Visual Studio when the DLL and the XML file of the same name are in the same directory.  Please refer to the Readme.txt file for more information.

  • Microsoft SharePoint Developer Documentation Team Blog

    SharePoint 2010 MSDN Developer Center Launch!

    • 0 Comments

    (Cross-posted from Randall's blog.) 

    Hello SharePoint Developers!

    I am thrilled to announce the launch of the SharePoint 2010 Developer Center!  Here is the only URL you need to remember for official SharePoint developer documentation and resources: http://msdn.microsoft.com/sharepoint

    As you may already be aware, SharePoint 2010 is a huge release for developers.  Start ramping up today on the new features and explore the possibilities!

    Here is what we have available for you right now to get started on your SharePoint 2010 development projects:

    ·         Getting Started videos and downloads
    Learn about Silverlight, the client-side object model, custom workflow, sandboxed solutions, accessing external data, and more!

    ·         Advanced Developer Training videos and downloads
    Self-paced, black-belt learning for working with SharePoint developer features such as Enterprise Content Management, Enterprise Search, Application Lifecycle Management, and more!

    ·         What’s New for Developers

    ·         Upgrade Resources for Developers moving from 2007 to 2010. Find out what’s new and changed, even down to a granular list of deprecated APIs

    ·         Developer Downloads, including SharePoint Foundation 2010, SharePoint Designer 2010, tools, code samples, and much more!

    ·         Software Development Kit (SDK) and API reference documentation, which is also available as context-sensitive Help in Visual Studio 2010!

    ·         Developer Best Practices, including disposing object, handling large lists, and writing efficient code

    ·         8 Developer-focused Resource Centers
    Resource centers aggregate useful links to SDK documentation, code samples, blogs, and other related content on a central theme. Resource centers typically highlight a SharePoint developer feature or a common customization task.  Check out our Business Connectivity Services and Excel Services Resource Centers today... we will have more going live in the coming weeks!

    There are so many resources on each of these pages, that it’s better to visit the Developer Center than to explain every last detail in this blog post.

    Also, you can check out this great post from Erika Ehrli Cabral, whose team worked so hard on many of these new Developer Center pages: http://blogs.msdn.com/erikaehrli/archive/2010/05/12/office-2010-and-sharepoint-2010-launch-a-summary-of-technical-content-that-matters-to-developers.aspx

     Let’s write some SharePoint code!

    - Randall

     

    Follow the SharePoint MSDN team on twitter for the latest updates: http://twitter.com/sharepointdev

  • Microsoft SharePoint Developer Documentation Team Blog

    How to Create a Web Part with a Contextual Tab

    • 13 Comments

    This post will cover how to create a Web Part that opens a contextual tab on the Server ribbon in Microsoft SharePoint Foundation 2010. You will be working with Server ribbon XML, EcmaScript (JavaScript, JScript), and C# code. This solution will be a farm solution and will be built using Visual Studio 2010 Beta 2. If you have any questions, please feel free to leave a comment.

     The following will appear in a future version of the SDK. It is preliminary documentation and subject to change.

    First, you will create a new project. Click on File, New, and then Project.

    1. Under Visual C#, choose Empty SharePoint Project and enter ContextualTabWebPart for the Name. Click OK.

    2.       In the SharePoint Customization Wizard, choose Deploy as a farm solution. Click Finish.

    Now, you will implement the Web Part.

    3.  In the Solution Explorer, right click References and choose Add Reference.

    4.  On the Add Reference dialog, choose the .NET Tab. Select Microsoft.Web.CommandUI.dll. Click OK.

    5.  Right click on the ContextualTabWebPart project in the Solution Explorer and choose Add, New Item...

    6.   In the Add New Item dialog, choose Web Part. Enter ContextualTabWebPart as the name.

    7.  When the Web Part has been added and ContextualTabWebPart.cs file is shown, add the following using statements.

    using System.Xml;

    using Microsoft.Web.CommandUI;

     

    8.  Now, you need to implement the IWebPartPageComponentProvider interface as follows. You will work with this later.

    public class ContextualTabWebPart : WebPart, IWebPartPageComponentProvider

     

    9.  Next, you will create two global string variables for the ribbon XML. These two variables define the contextual tab and the group template. For a more in-depth discussion on defining a tab and group template, see How to Add a Tab to the Server Ribbon in SharePoint Foundation. In the contextualTab string, you will notice a ContextualGroup element. This element defines the following Tab element as a contextual tab. The Color attribute defines the color of the tab when it renders. The Id and ContextualGroupId are simply unique identifiers for the group. The Sequence attribute defines where the contextual tab will render. The following code implements the two global string variables.

            private string contextualTab = @"

       <ContextualGroup Color=""Magenta""

         Command=""CustomContextualTab.EnableContextualGroup""

         Id=""Ribbon.CustomContextualTabGroup""

         Title=""Custom Contextual Tab Group""

         Sequence=""502""

         ContextualGroupId=""CustomContextualTabGroup"">

              <Tab

                  Id=""Ribbon.CustomTabExample""

                  Title=""My Custom Tab""

                  Description=""This holds my custom commands!""

                  Command=""CustomContextualTab.EnableCustomTab""

                  Sequence=""501"">

                <Scaling

                  Id=""Ribbon.CustomTabExample.Scaling"">

                  <MaxSize

                    Id=""Ribbon.CustomTabExample.MaxSize""

                    GroupId=""Ribbon.CustomTabExample.CustomGroupExample""

                    Size=""OneLargeTwoMedium""/>

                  <Scale

                    Id=""Ribbon.CustomTabExample.Scaling.CustomTabScaling""

                    GroupId=""Ribbon.CustomTabExample.CustomGroupExample""

                    Size=""OneLargeTwoMedium"" />

                </Scaling>

                <Groups Id=""Ribbon.CustomTabExample.Groups"">

                  <Group

                    Id=""Ribbon.CustomTabExample.CustomGroupExample""

                    Description=""This is a custom group!""

                    Title=""Custom Group""

                    Command=""CustomContextualTab.EnableCustomGroup""

                    Sequence=""52""

                    Template=""Ribbon.Templates.CustomTemplateExample"">

                    <Controls

                      Id=""Ribbon.CustomTabExample.CustomGroupExample.Controls"">

                      <Button

                        Id=""Ribbon.CustomTabExample.CustomGroupExample.HelloWorld""

                        Command=""CustomContextualTab.HelloWorldCommand""

                        Sequence=""15""

                        Description=""Says hello to the World!""

                        LabelText=""Hello, World!""

                        TemplateAlias=""cust1""/>

                      <Button

                        Id=""Ribbon.CustomTabExample.CustomGroupExample.GoodbyeWorld""

                        Command=""CustomContextualTab.GoodbyeWorldCommand""

                        Sequence=""17""

                        Description=""Says good-bye to the World!""

                        LabelText=""Good-bye, World!""

                        TemplateAlias=""cust2""/>

                    </Controls>

                  </Group>

                </Groups>

              </Tab>

       </ContextualGroup>";

     

            private string contextualTabTemplate = @"

              <GroupTemplate Id=""Ribbon.Templates.CustomTemplateExample"">

                <Layout

                  Title=""OneLargeTwoMedium"" LayoutTitle=""OneLargeTwoMedium"">

                  <Section Alignment=""Top"" Type=""OneRow"">

                    <Row>

                      <ControlRef DisplayMode=""Large"" TemplateAlias=""cust1"" />

                    </Row>

                  </Section>

                  <Section Alignment=""Top"" Type=""TwoRow"">

                    <Row>

                      <ControlRef DisplayMode=""Medium"" TemplateAlias=""cust2"" />

                    </Row>

                    <Row>

                      <ControlRef DisplayMode=""Medium"" TemplateAlias=""cust3"" />

                    </Row>

                  </Section>

                </Layout>

              </GroupTemplate>";

     

    10.  Create a new string property called DelayScript. DelayScript contains EcmaScript (JavaScript, JScript) that adds and registers your custom page component. We will create the custom page component later in this topic. The _addCustomPageComponent method creates your custom page component and adds it to the page manager. Every Web Part has a page component, and you will use the Web Part's page component id when you create a custom page component object. This is necessary to associate the Web Part with the page component to enable contextually switching to your custom ribbon tab. The _registerCustomPageComponent method registers your EcmaScript file when the page loads. The following code implements DelayScript .

            public string DelayScript

            {

                get

                {

                    string webPartPageComponentId = SPRibbon.GetWebPartPageComponentId(this);

                    return @"

    <script type=""text/javascript"">

    //<![CDATA[

     

                function _addCustomPageComponent()

                {

                    var _customPageComponent = new ContextualTabWebPart.CustomPageComponent('" + webPartPageComponentId + @"');

                    SP.Ribbon.PageManager.get_instance().addPageComponent(_customPageComponent);

                }

     

                function _registerCustomPageComponent()

                {

                    SP.SOD.registerSod(""CustomContextualTabPageComponent.js"", ""\/_layouts\/CustomContextualTabPageComponent.js"");

                    SP.SOD.executeFunc(""CustomContextualTabPageComponent.js"", ""ContextualWebPart.CustomPageComponent"", _addCustomPageComponent);

                }

                SP.SOD.executeOrDelayUntilScriptLoaded(_registerCustomPageComponent, ""sp.ribbon.js"");

    //]]>

    </script>";

                }

            }

    11.  Create a new function called AddContextualTab. Inside the AddContextualTab method, you will insert code to register the contextual tab and custom templates with the ribbon. The Microsoft.Web.CommandUI.Ribbon.RegisterDataExtension method will be used to register the ribbon extensions. RegisterDataExtension tells the ribbon where to load the XML passed into it. We will use the ids of the ContextualTabs and Templates elements in CMDUI.xml. The following code implements the AddContextualTab method.

            private void AddContextualTab()

            {

     

                //Gets the current instance of the ribbon on the page.

                Microsoft.Web.CommandUI.Ribbon ribbon = SPRibbon.GetCurrent(this.Page);

     

                //Prepares an XmlDocument object used to load the ribbon extensions.

                XmlDocument ribbonExtensions = new XmlDocument();

     

                //Load the contextual tab XML and register the ribbon extension.

                ribbonExtensions.LoadXml(this.contextualTab);

                ribbon.RegisterDataExtension(ribbonExtensions.FirstChild, "Ribbon.ContextualTabs._children");

     

                //Load the custom templates and register the ribbon extension.

                ribbonExtensions.LoadXml(this.contextualTabTemplate);

                ribbon.RegisterDataExtension(ribbonExtensions.FirstChild, "Ribbon.Templates._children");

            }

     

    12.  Now, you need to implement the WebPartContextualInfo property of the IWebPartPageComponentProvider interface. You can implement the interface by right clicking on IWebPartPageComponentProvider and choosing Implement Interface, Implement Interface Explicitly.

     

    This interface lets the ribbon know when a Web Part has been selected and which contextual group and tab to show. When you add the contextual group, you send it the id of the contextual group, the VisibilityContext, and the Command. The id maps to the Id property of the ContextualGroup element in the ribbon XML. The VisibilityContext is used to group controls in order to show or hide them. The Command parameter maps to the Command of the ContextualGroup element in the ribbon XML. You will also add the tab that was defined in the ribbon XML. You only need to pass in the Id and the VisibilityContext parameters for the tab.

    Insert the following code for the WebPartContextualInfo.

            public WebPartContextualInfo WebPartContextualInfo

            {

                get

                {

                    WebPartContextualInfo info = new WebPartContextualInfo();

                    WebPartRibbonContextualGroup contextualGroup = new WebPartRibbonContextualGroup();

                    WebPartRibbonTab ribbonTab = new WebPartRibbonTab();

     

                    //Create the contextual group object and initialize its values.

                    contextualGroup.Id = "Ribbon.CustomContextualTabGroup";

                    contextualGroup.Command = "CustomContextualTab.EnableContextualGroup";

                    contextualGroup.VisibilityContext = "CustomContextualTab.CustomVisibilityContext";

     

                    //Create the tab object and initialize its values.

                    ribbonTab.Id = "Ribbon.CustomTabExample";

                    ribbonTab.VisibilityContext = "CustomContextualTab.CustomVisibilityContext";

     

                    //Add the contextual group and tab to the WebPartContextualInfo.

                    info.ContextualGroups.Add(contextualGroup);

                    info.Tabs.Add(ribbonTab);

                    info.PageComponentId = SPRibbon.GetWebPartPageComponentId(this);

     

                    return info;

                }

            }

     

     

    13.  Next, you will implement the OnPreRender method. This allows us to add elements to the ribbon before it is rendered on the page. Inside OnPreRender you will call the AddContextualTab method and register the DelayScript with the ClientScriptManager. The following code implements OnPreRender.

            protected override void OnPreRender(EventArgs e)

            {

                base.OnPreRender(e);

     

                this.AddContextualTab();

     

                ClientScriptManager clientScript = this.Page.ClientScript;

                clientScript.RegisterClientScriptBlock(this.GetType(), "ContextualTabWebPart", this.DelayScript);

     

            }

     

    The Web Part is complete. Next, you will create the page component. A page component is an EcmaScript (JavaScript, JScript) object used to interact with the Server ribbon. It enables commands on the ribbon and responds to the commands you define in the ribbon XML. The page component has required functions in order for it to operate properly. The following table lists the required functions and their purpose.

    Function

    Purpose

    init

    Initializes the page component.

    getFocusedCommands

    Returns a list of the focused commands. Your page component is called for the commands only if it has the focus

    getGlobalCommands

    Returns a list of the global commands. Your page component is called for commands regardless of focus.

    isFocusable

    Specifies if the page component can receive focus.

    canHandleCommand

    Defines if the page component can handle a command sent to it.

    handleCommand

    Handles the commands sent to the page component.

    getId

    Returns the id of the page component. This is used to associate a control with a page component.

     

    There are also two optional functions. These functions will not be defined in this example.

    Function

    Purpose

    yieldFocus

    Specifies the code that is run when the page component loses focus.

    receiveFocus

    Specifies the code that is run when the page component receives focus.

     

    In order for the page component to operate properly, you will have to deploy the file using a Module.

    14.  In the Solution Explorer, right click on the ContextualTabWebPart project and select Add, New Item.

    15.  In the Add New Item dialog, choose the Module template and type CustomContextualTabPageComponent as the Name. Click Add.

    16.  You will not need the files that are added by default. Select Elements.xml and Sample.txt in the Solution Explorer and delete them.

    17.  Now, you need to add the EcmaScript (JavaScript, JScript) file. Right click on CustomContextualTabPageComponent and select Add, New Item.

    18.  Under Visual C#, choose Web in the Installed Templates list. Select the Jscript File type and enter CustomContextualTabPageComponent as the name.

    19.  You will need to set the deployment location to make sure the file goes into the _layouts directory. To do that, select CustomContextualTabPageComponent.js in the Solution Explorer. In the Properties window, set the Deployment Type to Root File. Open the Deployment Location property and set the Path to Template\Layouts.

    The following code will go into the CustomContextualTabPageComponent.js file to implement your custom page component.

    Type.registerNamespace('ContextualTabWebPart');

     

    var _webPartPageComponentId;

    ContextualTabWebPart.CustomPageComponent = function ContextualTabWebPart_CustomPageComponent(webPartPcId) {

        this._webPartPageComponentId = webPartPcId;

        ContextualTabWebPart.CustomPageComponent.initializeBase(this);

    }

    ContextualTabWebPart.CustomPageComponent.prototype = {

     

        init: function ContextualTabWebPart_CustomPageComponent$init() {  },

     

        getFocusedCommands: function ContextualTabWebPart_CustomPageComponent$getFocusedCommands() {

            return ['CustomContextualTab.EnableCustomTab', 'CustomContextualTab.EnableCustomGroup', 'CustomContextualTab.HelloWorldCommand', 'CustomContextualTab.GoodbyeWorldCommand'];

        },

     

        getGlobalCommands: function ContextualTabWebPart_CustomPageComponent$getGlobalCommands() {

            return [];

        },

     

        isFocusable: function ContextualTabWebPart_CustomPageComponent$isFocusable() {

            return true;

        },

       

        canHandleCommand: function ContextualTabWebPart_CustomPageComponent$canHandleCommand(commandId) {

            //Contextual Tab commands

            if ((commandId === 'CustomContextualTab.EnableCustomTab') || (commandId === 'CustomContextualTab.EnableCustomGroup') || (commandId === 'CustomContextualTab.HelloWorldCommand') || (commandId === 'CustomContextualTab.GoodbyeWorldCommand')) {

                return true;

            }

        },

     

        handleCommand: function ContextualTabWebPart_CustomPageComponent$handleCommand(commandId, properties, sequence) {

     

            if (commandId === 'CustomContextualTab.HelloWorldCommand') {

                alert('Hello, world!');

            }

            if (commandId === 'CustomContextualTab.GoodbyeWorldCommand') {

                alert('Good-bye, world!');

            }

        },

     

        getId: function ContextualTabWebPart_CustomPageComponent$getId() {

            return this._webPartPageComponentId;

        }

    }

     

     

    ContextualTabWebPart.CustomPageComponent.registerClass('ContextualTabWebPart.CustomPageComponent', CUI.Page.PageComponent);

    SP.SOD.notifyScriptLoadedAndExecuteWaitingJobs("CustomContextualTabPageComponent.js");

     

    Notice that getFocusedCommands returns the Command properties that you defined in the ribbon XML above. In canHandleCommand you return true to signify that your page component can respond to the specified commands. When creating this object, you use the webPartPcId parameter to set the custom page component id. This is set to the same value as the Web Part’s page component id to associate the Web Part and page component through the getId method.

    20.  To test the code, press F5 to deploy the solution.

    21.  Open your site and put the page into Edit mode.

    22.  In the Insert tab, click the Web Part button.

    23.  In the Web Part Adder, select the Custom category.

    24.  In the list of Web Parts, select ContextualTabWebPart. Click Add.

    25.  Once the Web Part is added to the page, click the ContextualTabWebPart.

    26.  Notice the Custom Contextual Tab Group tab that shows up on selection.

  • Microsoft SharePoint Developer Documentation Team Blog

    How to Add a Tab to the Ribbon in SharePoint Foundation

    • 13 Comments

    (Before he left for a week of laying on various tropical beaches with drinks in his hand, Dallas asked me to post this for him. Since I'm stuck in the rainy Northwest and had nothing better to do, I was happy to oblige him.) 

    The ribbon has unified the command surface inside of SharePoint. It is now the primary point of entry for working with items inside of SharePoint. As such the ribbon is extensible through the use of declarative XML in a Feature.

    This post will cover how to add a new tab to the ribbon in Microsoft SharePoint Foundation 2010. It will also, by necessity, cover how to create a group, controls, template, and scaling behavior. I will build this solution in Visual Studio 2010 Beta 2 and as a sandboxed solution for the ease of deployment.

    The following will appear in a future version of the SDK. It is preliminary documentation and subject to change.

    First, you will want to create a new project. Click on File, New, and then Project.

    Under Visual C#, choose Empty SharePoint Project and enter AddARibbonTab for the Name. Click OK.

    In the SharePoint Customization Wizard, choose Deploy as a sandboxed solution. Click Finish.

    In the Solution Explorer, right click on Features and choose Add Feature.

    Change the Title of the Feature to Custom Ribbon Tab. Also, rename Feature1 in the Solution Explorer to CustomRibbonTab.

    Right click on the AddARibbonTab project in the Solution Explorer and choose Add, New Item…

    In the Add New Item dialog, choose the Empty Element template. Enter CustomRibbonTab as the Name.

    In the Elements.xml file, insert the following CustomAction element. The Location attribute tells the CustomAction where to apply the customization. The following list explains the acceptable values.

    Value

    Description

    CommandUI.Ribbon

    Customization appears everywhere for the specified RegistrationId.

    CommandUI.Ribbon.ListView

    Customization appears when the list view Web Part is present.

    CommandUI.Ribbon.EditForm

    Customization appears on the edit form.

    CommandUI.Ribbon.NewForm

    Customization appears on the new form.

    CommandUI.Ribbon.DisplayForm

    Customization appears on the display form.

     

    <?xml version="1.0" encoding="utf-8"?>

    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">

      <CustomAction

        Id="MyCustomRibbonTab"

        Location="CommandUI.Ribbon.ListView"

        RegistrationId="101"

        RegistrationType="List">

     

      </CustomAction>

    </Elements>

     

    Add the following elements to define the ribbon extension and tab. The Location on the CommandUIDefinition element defines where the controls inside of it will render. In this example, you reference the Tabs collection of the ribbon. The _children convention tells the ribbon to insert the following XML, whether it is a tab, group, or control, into the collection of tabs. The Sequence attribute on the Tab element defines where the tab will render in regards to other tabs. The default tabs use multiples of 100, so the Sequence attribute should not be a multiple of 100 to prevent collisions.

    <CommandUIExtension>

          <CommandUIDefinitions>

            <CommandUIDefinition

              Location="Ribbon.Tabs._children">

              <Tab

                Id="Ribbon.CustomTabExample"

                Title="My Custom Tab"

                Description="This holds my custom commands!"

                Sequence="501">

     

    When creating a custom tab, you must define how the tab will scale when controls are added. This is handled through the use of the Scaling element along with a GroupTemplate. The MaxSize element defines the maximum size of the controls in the group. The Scale element defines how the group will scale in different situations. The GroupId attribute associates a group with the scale size. The Size attribute is defined by the Layout element, which is defined later in this topic.

                <Scaling

                  Id="Ribbon.CustomTabExample.Scaling">

                  <MaxSize

                    Id="Ribbon.CustomTabExample.MaxSize"

                    GroupId="Ribbon.CustomTabExample.CustomGroupExample"

                    Size="OneLargeTwoMedium"/>

                  <Scale

                    Id="Ribbon.CustomTabExample.Scaling.CustomTabScaling"

                    GroupId="Ribbon.CustomTabExample.CustomGroupExample"

                    Size="OneLargeTwoMedium" />

                </Scaling>

     

    Now, you will define the groups of controls that will appear on the tab. The Group element contains the usual attributes along with a Template attribute. The Template attribute references the GroupTemplate that is defined later in this topic. The Controls element contains the controls that will render in the group. These can be buttons, dropdowns, and other control types. You can find a list in the SDK at this address: http://msdn.microsoft.com/en-us/library/ee537017(office.14).aspx. The controls inside the group must define the TemplateAlias and Command attributes. Like tabs, each control has a Sequence attribute that defines where they will render in the group. The default controls are based on multiples of 10, so any custom controls should not use a multiple of 10 to avoid collisions. The Command attribute is used by the CommandUIHandler defined later in this topic but is required even if the CommandUIHandler is not specified. The TemplateAlias attribute defines where the control will render in relationship to the GroupTemplate.

                <Groups Id="Ribbon.CustomTabExample.Groups">

                  <Group

                    Id="Ribbon.CustomTabExample.CustomGroupExample"

                    Description="This is a custom group!"

                    Title="Custom Group"

                    Sequence="52"

                    Template="Ribbon.Templates.CustomTemplateExample">

                    <Controls Id="Ribbon.CustomTabExample.CustomGroupExample.Controls">

                      <Button

                        Id="Ribbon.CustomTabExample.CustomGroupExample.HelloWorld"

                        Command="CustomTabExample.HelloWorldCommand"

                        Sequence="15"

                        Description="Says Hello to the World!"

                        LabelText="Hello, World!"

                        TemplateAlias="cust1"/>

                      <Button

                        Id="Ribbon.CustomTabExample.CustomGroupExample.GoodbyeWorld"

                        Command="CustomTabExample.GoodbyeWorldCommand"

                        Sequence="17"

                        Description="Says Good-bye to the World!"

                        LabelText="Good-bye, World!"

                        TemplateAlias="cust2"/>

                      <Button

                        Id="Ribbon.CustomTabExample.CustomGroupExample.LoveWorld"

                        Command="CustomTabExample.LoveWorldCommand"

                        Sequence="19"

                        Description="Says I &lt;3 the World!"

                        LabelText="I &lt;3 you, World!"

                        TemplateAlias="cust3"/>

                    </Controls>

                  </Group>

                </Groups>

              </Tab>

            </CommandUIDefinition>

     

    With that code in place, you have finished the first CommandUIDefinition that includes the tab, groups, and controls. You need to define how the controls will render inside of the group. You do this using a GroupTemplate element in another CommandUIDefinition. The CommandUIDefinition will have a Location of Ribbon.Templates._children. This follows the pattern for Groups and Tabs.

    The GroupTemplate element contains a Layout element with Section and Row elements. The Layout element has a LayoutTitle that is used for the Size attribute on the MaxSize and Scale elements. The Section elements define the position of the controls as well as how many rows will render inside that section. The Row element contains one or more ControlRef elements. ControlRef elements define how your controls will display. The DisplayMode attribute can have the following values:

    Value

    Description

    Small

    Renders as a small icon without label text.

    Medium

    Renders as a 16x16 icon with label text.

    Large

    Renders as a 32x32 icon with label text.

    Text

    Renders as text only.

     

    The ControlRef elements also define the TemplateAlias values that you used for the TemplateAlias attribute on the buttons. Note that only one control per group can use this value. You cannot have two controls with the same TemplateAlias unless it is an OverflowArea. You can reuse the TemplateAlias across different groups though. There is also an OverflowArea element that defines how controls will render if there are too many controls in a group. The TemplateAlias attributes that refer to OverflowAreas in the GroupTemplate can be used on multiple controls.

    In this example, you will define two sections for rendering the controls. One section will be a row of large buttons while the other section will contain two rows of medium-sized buttons.

            <CommandUIDefinition Location="Ribbon.Templates._children">

              <GroupTemplate Id="Ribbon.Templates.CustomTemplateExample">

                <Layout

                  Title="OneLargeTwoMedium"

                  LayoutTitle="OneLargeTwoMedium">

                  <Section Alignment="Top" Type="OneRow">

                    <Row>

                      <ControlRef DisplayMode="Large" TemplateAlias="cust1" />

                    </Row>

                  </Section>

                  <Section Alignment="Top" Type="TwoRow">

                    <Row>

                      <ControlRef DisplayMode="Medium" TemplateAlias="cust2" />

                    </Row>

                    <Row>

                      <ControlRef DisplayMode="Medium" TemplateAlias="cust3" />

                    </Row>

                  </Section>

                </Layout>

              </GroupTemplate>

            </CommandUIDefinition>

          </CommandUIDefinitions>

     

    The final step is to write handlers for the buttons. These are inside CommandUIHandler elements. The Command attribute is a unique name for the command and used for the Command attribute on controls. The CommandAction attribute contains the action that is performed for the control. This can be JavaScript, an URL, or anything that was previously contained in an UrlAction element.

          <CommandUIHandlers>

            <CommandUIHandler

              Command="CustomTabExample.HelloWorldCommand"

              CommandAction="javascript:alert('Hello, world!');" />

            <CommandUIHandler

              Command="CustomTabExample.GoodbyeWorldCommand"

              CommandAction="javascript:alert('Good-bye, world!');" />

            <CommandUIHandler

              Command="CustomTabExample.LoveWorldCommand"

              CommandAction="javascript:alert('I love you, world!');" />

          </CommandUIHandlers>

        </CommandUIExtension>

     

    With the addition of the CommandUIHandlers, you have finished your Elements.xml file. Press F5 to deploy your solution. Then, navigate to the Shared Documents folder. You should see the Custom Tab. Click on Custom Tab to open it. Click any of the buttons to show the associated alert.

    Hopefully this walkthrough has been helpful! If you have any questions or concerns, please let me know in the comments.

     

    Full Code Listing:

    <?xml version="1.0" encoding="utf-8"?>

    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">

      <CustomAction

        Id="MyCustomRibbonTab"

        Location="CommandUI.Ribbon.ListView"

        RegistrationId="101"

        RegistrationType="List">

          <CommandUIExtension>

            <CommandUIDefinitions>

              <CommandUIDefinition

                Location="Ribbon.Tabs._children">

                <Tab

                  Id="Ribbon.CustomTabExample"

                  Title="My Custom Tab"

                  Description="This holds my custom commands!"

                  Sequence="501">

                <Scaling

                  Id="Ribbon.CustomTabExample.Scaling">

                  <MaxSize

                    Id="Ribbon.CustomTabExample.MaxSize"

                    GroupId="Ribbon.CustomTabExample.CustomGroupExample"

                    Size="OneLargeTwoMedium"/>

                  <Scale

                    Id="Ribbon.CustomTabExample.Scaling.CustomTabScaling"

                    GroupId="Ribbon.CustomTabExample.CustomGroupExample"

                    Size="OneLargeTwoMedium" />

                </Scaling>

                <Groups Id="Ribbon.CustomTabExample.Groups">

                  <Group

                    Id="Ribbon.CustomTabExample.CustomGroupExample"

                    Description="This is a custom group!"

                    Title="Custom Group"

                    Sequence="52"

                    Template="Ribbon.Templates.CustomTemplateExample">

                    <Controls Id="Ribbon.CustomTabExample.CustomGroupExample.Controls">

                      <Button

                        Id="Ribbon.CustomTabExample.CustomGroupExample.HelloWorld"

                        Command="CustomTabExample.HelloWorldCommand"

                        Sequence="15"

                        Description="Says hello to the World!"

                        LabelText="Hello, World!"

                        TemplateAlias="cust1"/>

                      <Button

                        Id="Ribbon.CustomTabExample.CustomGroupExample.GoodbyeWorld"

                        Command="CustomTabExample.GoodbyeWorldCommand"

                        Sequence="17"

                        Description="Says good-bye to the World!"

                        LabelText="Good-bye, World!"

                        TemplateAlias="cust2"/>

                      <Button

                        Id="Ribbon.CustomTabExample.CustomGroupExample.LoveWorld"

                        Command="CustomTabExample.LoveWorldCommand"

                        Sequence="19"

                        Description="Says I love the World!"

                        LabelText="I love you, World!"

                        TemplateAlias="cust3"/>

                    </Controls>

                  </Group>

                </Groups>

              </Tab>

            </CommandUIDefinition>

            <CommandUIDefinition Location="Ribbon.Templates._children">

              <GroupTemplate Id="Ribbon.Templates.CustomTemplateExample">

                <Layout

                  Title="OneLargeTwoMedium"

                  LayoutTitle="OneLargeTwoMedium">

                  <Section Alignment="Top" Type="OneRow">

                    <Row>

                      <ControlRef DisplayMode="Large" TemplateAlias="cust1" />

                    </Row>

                  </Section>

                  <Section Alignment="Top" Type="TwoRow">

                    <Row>

                      <ControlRef DisplayMode="Medium" TemplateAlias="cust2" />

                    </Row>

                    <Row>

                      <ControlRef DisplayMode="Medium" TemplateAlias="cust3" />

                    </Row>

                  </Section>

                </Layout>

              </GroupTemplate>

            </CommandUIDefinition>

          </CommandUIDefinitions>

          <CommandUIHandlers>

            <CommandUIHandler

              Command="CustomTabExample.HelloWorldCommand"

              CommandAction="javascript:alert('Hello, world!');" />

            <CommandUIHandler

              Command="CustomTabExample.GoodbyeWorldCommand"

              CommandAction="javascript:alert('Good-bye, world!');" />

            <CommandUIHandler

              Command="CustomTabExample.LoveWorldCommand"

              CommandAction="javascript:alert('I love you, world!');" />

          </CommandUIHandlers>

        </CommandUIExtension>

      </CustomAction>

    </Elements>

     

  • Microsoft SharePoint Developer Documentation Team Blog

    SharePoint 2010 Beta Release Known Issues

    • 0 Comments

    This post lists and addresses known issues that developers have been frequently encountering while working with the Beta release of Microsoft SharePoint 2010. These issues relate only to the Beta versions of Microsoft SharePoint Foundation 2010 and Microsoft SharePoint Server 2010, and are limited to areas that concern developers specifically. See Microsoft Office Servers Beta 2 Known Issues/ReadMe for a broader list of known issues with the Beta release of Office 14 server applications.

    Installation Issues:

    The issues listed here supplement the guidance and instructions provided in Setting up the Development Environment for SharePoint Server.

    • When you install on Microsoft Windows 7 or Windows Vista, make sure that WCF HTTP Activation and WCF non-HTTP Activation are set. If these Windows Features are not set, the configuration wizard will fail at task 8. Step 2, item 8 in Setting up the Development Environment for SharePoint Server contains a command that you can use to enable all of the required Windows Features, including WCF HTTP Activation and WCF non-HTTP Activation. The command in that topic contains line breaks, however, so you will have to remove the line breaks manually before running it.
    • Install the WCF hotfix. A hotfix that provides a method to support token authentication without transport security or message encryption in WCF is available for.NET Framework 3.5 SP1. Use this link for Windows Server 2008 and this link for Windows Server 2008 R2. The Windows Server 2008 fix also applies to Vista, while the Windows Server 2008 R2 fix also applies to Windows 7.
      If you don't have this fix installed, you will get an "Unrecognized attribute 'allowInsecureTransport'" error in ULS log. And most of the service applications will not run properly. If you are installing on Windows 7 and have previously installed Visual Studio 2010, you may need to replace an installer file, as described in this blog post.
    • If after installing SharePoint 2010 you are not getting ULS logs, either disable Windows Firewall or create an exception in Windows Firewall for WSSTracing.exe.
    • We do not currently support installation on K or KN editions of Windows 7.
    • Web Application Companions (WAC), SharePoint Search, and SharePoint User Profile Sync cannot be installed on Windows 7.

    Development Issues:

    • When you create custom solutions with Visual Studio 2010, set the target framework to .NET Framework 3.5.
    • When you add resources to a Mapped Folder in Visual Studio 2010, the default build action is set to Embedded Resource. If you do not set the build action to Content or None, the files in the Mapped Folder will not be included in the WSP.
    • Deployment of BDC models with the Business Data Connectivity Model template in Microsoft Visual Studio 2010 does not yet work in SharePoint Foundation 2010. SharePoint Foundation is missing the feature event receiver that enables the import of BDC models. This does work in SharePoint Server, and before RTM Microsoft will release code for a feature event receiver that you can add to your BDC projects to deploy to SharePoint Foundation.
    • References to assemblies in "*\14\Templates\Layouts\ClientBin" (including Microsoft.SharePoint.Client.Silverlight.dll and Microsoft.SharePoint.Client.Silverlight.Runtime.dll) result in paths that are too long for Visual Studio 2010. Andrew Connell describes this problem and proposes a work-around in this blog post.
    • Sites created from SharePoint Designer 2010 do not have the AssociatedOwnerGroup property of SPWeb set by default. As a result, site owners cannot complete workflow tasks that are not assigned to them. When they try to do this, they receive error messages indicating that that workflow tasks were rolled back because the users do not have the correct permissions. Workflows use the AssociatedOwnerGroup property to determine who can override the rollbacks. To fix this, set the AssociatedOwnerGroup property with code, or create a new site from the browser.
    • Some assemblies, such as Microsoft.SharePoint.Publishing, appear in some cases to have a dependency on an incorrect version of the System.Web.DataVisualization assembly. The incorrect reference causes build failures. If you see this problem, add a reference to the correct version of System.Web.DataVisualization on your system. If your installation is on the C drive, that assembly will be located here:

    C:\Program Files (x86)\Microsoft  Chart Controls\Assemblies\System.Web.DataVisualization.dll

    • If you install or upgrade a custom solution built on Microsoft Office SharePoint Server 2007 that embeds the SearchBoxEx Web Control into your custom master page, you will get an error indicating that "the type or namespace name 'SearchBoxEx' does not exist in the namespace 'Microsoft.SharePoint.Portal.WebControls'." This will not happen if you simply add the Search Box Web Part to a Web Part page. This will be fixed in the RTM version. You can work around this issue by updating your customized master page to include this tag:

    <%@ Register Tagprefix="MSSWC" Namespace="Microsoft.SharePoint.Portal.WebControls" Assembly="Microsoft.Office.Server.Search, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

     Once you have added this tag,  you can then embed the SearchBoxEx Web Control with this tag:

    <MSSWC:SearchBoxEx id="SearchBox"…>

    The <SPSWC:SearchBoxEx id="SearchBox"…> tag should also work as long as the Web form has been registered to use the Microsoft.SharePoint.Portal.WebControls namespace in the Search assembly.

    • If you are testing your installation with Internet Explorer on your server machine, turn off IE Enhanced Security Configuration in your Server Manager. This will make certain site operations, such as "New|Edit" dialogs, work more smoothly.
  • Microsoft SharePoint Developer Documentation Team Blog

    SharePoint 2010 SDK Code Samples Posted to Code Gallery

    • 1 Comments

    For the SharePoint 2010 release, we’re trying something a little different with our sample code solutions. During the Beta timeframe, we’re going to be posting them to Code Gallery, rather than waiting to release them in the SharePoint 2010 SDK for the first time at RTM. This will let developers benefit from having the code samples available as early as possible. And we’re hoping it’ll benefit the code samples by having the SharePoint developer community giving us feedback on the samples and how we can make them better. We’ll include the code samples in their final form in the SharePoint 2010 SDK download at RTM.

    We’ll be keeping the list below up-to-date each time we release a new code sample, so you might want to bookmark this post. (We’ve already got three samples posted, and the SharePoint 2010 Beta isn’t scheduled for public availability until next month.)

    Unless otherwise noted, each code sample is written in C#.

    SharePoint Foundation 2010 Code Samples

    Implementation of IBackupRestore 

    This sample is a custom content class that implements Microsoft.SharePoint.Administration.Backup.IBackupRestore. Objects that instantiate this interface appear in the backup/restore UI of the SharePoint Central Administration application as items that can be selected for backup or restoration.

    SharePoint Server 2010 Code Samples

    Activity Feeds Console Application

    A console application that demonstrates the basic functions of a custom activity feed gatherer application.

    This sample creates a custom activity feed gatherer and demonstrates how to use the new Activity Feed object model in Microsoft SharePoint Server 2010. The sample creates custom ActivityTemplate, ActivityType, and ActivityEvent objects and shows how to publish and multicast events from a custom gatherer. Console output verifies that each step in the application is finished.

    Social Data Statistics Web Part 

    A Web part that displays social data statistics.

    This sample consists of a Microsoft Visual Studio 2010 SharePoint Visual Web part project. After you build and deploy this project on your Microsoft SharePoint Server 2010 site, you can add this Web part to any page where you want to display statistics for the social tagging activities of your users. The Web part displays the following information in three tables:

    ·         Each URL that has been tagged, and the terms with which each URL has been tagged.

    ·         Each term that has been used in a social tag, and the number of times that term has been used.

    ·         Each user who has added a social tag, and the number of times that user has tagged URLs.

    The sample demonstrates how to use the new Social Data object model in SharePoint Server 2010. It also takes advantage of the SharePoint Visual Web Part template, one of the new SharePoint templates that you can use in Visual Studio 2010.

  • Microsoft SharePoint Developer Documentation Team Blog

    Got Code?

    • 2 Comments

    Contribute a Code Sample and Get Your Name in the SharePoint 2010 SDK

    We’re looking for experienced SharePoint developers to share their skill and technical expertise with the SharePoint community. You’ll help your fellow SharePoint developers, and receive full attribution in the SharePoint SDK for doing so!

    What we’re looking for are short code samples, what we on documentation teams tend to think of as ‘snippets’. A handful of lines that illustrate a discreet task or show how to exercise a specific piece of the object model, rather than a full-blown solution that addresses an entire scenario. Basically, the short code samples you’d find in a typical reference topic like this one.

    In particular, we’re on the hunt for code samples that do one or more of the following:

    ·         Show developers how to accomplish common SharePoint tasks programmatically

    ·         Illustrate best coding practices in using the SharePoint object model

    ·         Demonstrate how to avoid pitfalls when using lesser-known areas of the SharePoint object model

    ·         Or otherwise show off the power and flexibility of developing SharePoint solutions

    If you’re an experienced SharePoint developer, you probably have a toolbox of code snippets like these already; sections of code that you use over and over to perform the same routine tasks, or pieces of code that you’re particularly proud of having come up with as work-arounds for some of the, um, “eccentricities” of the SharePoint object model.

    What we’re asking is that you share your hard-won knowledge by letting us publish your code samples in our SDK reference topics. In return, we want to make sure you get full credit, by giving you attribution right in the topic where the code sample appears. This includes a link to your company site. You can see an early example of this in this reference topic for the CreateTaskWithContentType class.

    The SDK gets more real-world code samples, and you get increased visibility within the larger SharePoint developer community.

    To submit a code sample, just shoot us an email including your code sample(s) at gotcode@microsoft.com. Include a short description of what each code sample does, or what task you would use the code sample to accomplish. Oh, and if there are any prerequisites that need to be specified for your code sample to run successfully, that’d be great to know as well. (For example, the code sample on the SPList class topic lists a few using directives, and the existence of an .aspx page containing a label control, as prerequisites.)

    I’ve attached a zip with our code sample guidelines and some sample data to this post. These are the best practices for writing code samples that we give our external partners who write samples for us. For the best chance of getting your sample included in the SDK, take a look at the best practices for code snippets (the guidelines are really short, and won’t take more than a few minutes to review, I promise.)

    Now, since the SharePoint 2010 Betas aren’t due out until November, for now we’re talking about code snippets written against the WSS 3.0 or MOSS 2007 object models. Go ahead and send them our way. And once you’ve worked with the SharePoint 2010 Betas a bit, you’ll undoubtedly create some useful or illuminating code samples in fairly short order. Send those our way as well. You could end up with a byline in the SharePoint SDK!

    Any questions, feel free to ping gotcode@microsoft.com, or leave a comment.

  • Microsoft SharePoint Developer Documentation Team Blog

    First Look: SharePoint 2010 Developer Documentation Now Live on MSDN!

    • 0 Comments

    By now you’ve probably been hearing some of the big news coming out of the SharePoint Developer Conference being held this week in Las Vegas. Doubtlessly, there’ll be tons more great information coming out of the Conference over the next four days concerning what’s new and notable in SharePoint Foundation 2010 and SharePoint Server 2010. But if you weren’t lucky enough to make it to Vegas this year, or are there but can’t wait for the session on your favorite area of SharePoint development, then have we got something you’ll want to take a close look at:

    Introducing the SharePoint 2010 (Beta) Developer Center

    That’s right, this morning we launched the SharePoint 2010 (Beta) Developer Center on MSDN. We’re using this new, combined Developer Center to give you your first detailed, public technical information and instruction around both SharePoint Foundation and SharePoint Server 2010. This new sub-site of the revamped SharePoint Developer Center highlights some early videos, documentation, and hands-on lab walkthroughs to introduce you to the exciting developer features on both SharePoint Foundation 2010 and SharePoint Server 2010.

    But that‘s not all: we’ve also published a Beta release of the combined SharePoint 2010 SDK!

    You’ll definitely want to spend some time on the site, getting ramped up for when the SharePoint 2010 Betas are released in November.

    Learn SharePoint from the Ground Up

    Of particular interest to developers new to SharePoint will be the Get Started Developing on SharePoint 2010. We’ve put together a series of 10 modules to help you get your feet wet on some of the main areas of SharePoint development, including:

    ·         Building Web Parts

    ·         What Developers Need to Know About SharePoint 2010

    ·         Building Blocks for Web Part Development

    ·         Accessing Data and Objects with Server-Side APIs

    ·         Accessing Data and Objects with Client-Side APIs

    ·         Accessing External Data with Business Connectivity Services

    ·         Developing Business Processes with Workflows 

    ·         Creating Silverlight User Interfaces

    ·         Sandboxed Solutions for Web Parts

    ·         Creating Dialog Boxes and Ribbon Controls

    Each module includes multiple video lessons, as well as code samples and hands-on lab walkthroughs, to give you a firm grounding in the topics covered.

    Even experienced SharePoint developers will want to take a look at the modules that cover brand new development areas, like the client-side APIs, Silverlight user interfaces, sandboxed solutions, and the new ribbon user interface.

    Get Your First Look at What’s New for Developers in SharePoint 2010

    For an even deeper look at what’s new and notable in SharePoint Foundation and Server 2010, we’ve posted a Beta version of the combined SharePoint 2010 SDK. It’s packed with conceptual, procedural and reference material covering the major developmental areas of both Foundation and Server. All in all, it’s almost half a million words detailing how to develop SharePoint solutions.

    For example, take a look here for what’s new in SharePoint Foundation 2010, including:

    ·         Alerts Enhancements

    ·         Business Connectivity Services

    ·         Client Object Model

    ·         Events Improvements

    ·         Microsoft Synch Framework

    ·         Mobile Device Development Enhancements

    ·         Query Enhancements

    ·         Ribbon

    ·         Sandboxed Solutions

    ·         Service Application Framework 

    ·         Silverlight Integration and the Fluid Application Model

    ·         UI Improvements

    ·         Windows PowerShell for SharePoint

    ·         Workflow Improvements

    And take a look here for what’s new in SharePoint Server 2010, including:

    ·         User Profiles and Social Data

    ·         Business Connectivity Services (BCS)

    ·         Enterprise Content Management (ECM)

    ·         SharePoint Enterprise Search

    ·         PerformancePoint Services

    ·         Excel Services

    Some other places you might want to start:

    ·         If you’re newer to SharePoint development, you might want to spend some time in the Getting Started and Building Blocks sections of the SDK, getting a firm grounding in the basics.

    ·         If you’re coming to SharePoint from an ASP.NET development background, but sure and check out the Glide Path for ASP.NET Developers section, which is specifically aimed at developers transitioning from ASP.NET development to development on the SharePoint Foundation platform.

    Let Us Know What You Want

    Now, this SDK is a Beta release, so you’ll likely see some rough edges. But we’ve combined this SDK to cover both SharePoint Foundation and Server, and restructured it to present the continuum of SharePoint development in as logical and intuitive a way as we could. We then packed it with new and updated conceptual, procedural, and reference material.

    We’d love to hear what you think of what we’ve done. As always, as you read through the SDK, if you spot issues, don’t see the information you need, or have suggestions, please drop us a line and let us know how we can improve our developer documentation. It’s easy; just do one of the following:

    ·         Enter a comment in the MSDN ratings box

    ·         Email us directly at docthis (at) Microsoft.com

    ·         Email us through this blog

    Be sure and check back here often (or even better, subscribe to our RSS feed), as we plan on using the blog to preview draft versions of additional SDK content as it gets written.

  • Microsoft SharePoint Developer Documentation Team Blog

    How Should C# Property Syntax Signatures Appear in Office SDKs?

    • 7 Comments

    This post is to solicit your opinion about whether and how Microsoft should change the presentation of C# property declarations in SDK topics to take into account certain changes in the 3.0 version of C#.

    Every property of a managed class has a reference topic in the product’s offline SDK and a corresponding MSDN page. Near the top of the page is the declaration signature of the class, in a monospaced font, as it would look in each of several languages. For example, the SPList.AllowRssFeeds topic has the following for Visual Basic and C#:

    VB: Public ReadOnly Property AllowRssFeeds As Boolean

    C#: public bool AllowRssFeeds { get; }

    And for SPList.AlertTemplate, the topic has this:

    VB: Public Property AlertTemplate As SPAlertTemplate 

    C#: public SPAlertTemplate AlertTemplate { get; set; }

    In reality, nearly all managed code at Microsoft is written in C#. The syntax examples for other languages only show, approximately, what the declaration would have looked like if the class had been written in that language. Notice that whether or not the property is read-only can be conveyed in the VB with that language's ReadOnly keyword. But C#'s little-known readonly keyword can be applied to fields, not properties. So to indicate whether or not a property is read-only, the declaration adds "{ get; set; }", for read/write properties, or just "{ get; }", for read-only properties.

    This system has worked well even though the C# declarations were not literally correct syntax. Indeed, they worked well partly because they were not correct syntax. Since they were not valid declarations, there has been no danger that readers would think that the pseudo-declaration indicated anything about how the get and set accessors were implemented under the hood. Thus, the programming design principle of “information hiding” is preserved.

    But with C# 3.0, a declaration such as this one:

    A:

    public type SomeProperty { get; set; }

    is valid code and it would compile “as is.”  It is equivalent to the following code. In fact, it is transformed into the following code on an early pass of the compiler.

    B:

    private type someField;

    public type SomeProperty

    {

        get { return someField; }

        set { someField = value; }

    }

    The C# 3.0 syntax for a read-only wrapper property simply adds a “private” access modifier to the set accessor:

    C:

    public type SomeOtherProperty { get; private set; }

    which compiles to:

    D:

    private type someOtherField;

    public type SomeOtherProperty

    {

        get { return someField; }

    }

    ( Note by the way, that since both A and B compile to identical IL code, no code analysis tool, such as .Net Reflector or Visual Studio’s Object Browser, can determine whether the property’s source code originated as A or B. A parallel point applies to C and D.)

    The problem this creates for the property topics in our SDKs is that our presentation of read/write properties now can be mistaken for the actual implementation, especially by new developers who are coming to Microsoft managed code development after the release of C# 3.0 and are not familiar with the history of the syntax conventions on these pages.

    Such a misunderstanding can, in turn, lead developers to make mistaken assumptions about the property’s get and set accessors. Our current way of presenting a read/write property declaration in our SDKs implies, since the release of C# 3.0, that the property is a simple wrapper property. This, in turn, implies several things that may be false. Among them are:

    • The set accessor does no validation on the input.
    • The set and get accessors do not directly throw (or catch) any exceptions.
    • The get accessor is simply returning a field value as distinct from calculating a value from multiple fields.

    Two proposals have been made for how C# property declarations should look going forward.

    Explicit Labeling Proposal:

    Under this proposal, the read/write or read-only character of a property would be explicitly stated in a different font from the monospaced font of the declaration:

    public type SomeProperty [read/write]

    public type SomeOtherProperty [read-only]

    Put the ‘Pseudo’ Back in 'Pseudo-Code' Proposal:

    Under this proposal, the tradition of using pseudo-code to indicate the writeable status would be preserved, but the braces and semi-colons would be removed so that the presentation is once again not legal code.

    public type SomeProperty get set

    public type SomeOtherProperty get

    The Office developer documentation team would like you to vote on these proposals. One way is to add a comment to this post. If you are an MVP member of the Office Content Publishing Collaboration site, you also have the option of voting on this survey page.

    You may also, of course, vote to leave the property declarations just as they are, or make an alternate proposal.

    One final point: Although this survey is sponsored by Office Developer Documentation, the issue is relevant to all managed code SDKs (and to the way that Visual Studio’s Object Browser presents properties). Although it will take time for all branches of the company to align on a single policy, you should vote as though you were helping to set policy for all divisions of Microsoft. It is likely that, eventually, all the affected Microsoft teams will settle on a consistent manner of presenting C# properties. In other words, do not vote against a proposal merely because it is inconsistent with the current policy of some other SDK or tool.  

Page 1 of 2 (47 items) 12