Visual Studio 2010 RTM available for MSDN subscribers

Much anticipated and by many rated as the best Visual Studio version yet. It is now available at MSDN for MSDN subscibers.

Visit http://msdn.microsoft.com/subscriptions to pick up your copy.

Visual Studio 2010 will be officially launched at April 20th. By that time, SharePoint 2010 RTM will also be released to MSDN subscribers.

Great times ahead. Have fun playing around with this best version yet! 😉

Document Sets for the Enterprise

In my previous post, I talked about the very cool feature of assigning unique ID’s to documents within SharePoint 2010. Even more exiting was that we could actually very much influence the way these ID are generated. In this post, I will talk about another new cool feature that is much anticipated in the enterprise, Document Sets.

One of the most commonly asked questions by customers was whether it would be possible to assign metadata to a folder within a document library and have the documents within that folder inherit these properties. A second question was whether it would be possible to pre-fill a document library with a fixed folder structure, for example for projects and default documents. In 2007, we could assign metadata to folders, but these would not be inherited by the documents residing in it. The answer to the second question was that this could be done, but involved custom code. And changes forced a redeployment of the code. 

Document Sets 

In SharePoint 2010, Microsoft introduces the concept of Document Sets. Document Sets are content types that can contain other content types and are displayed as a folder in the document library. As with all content types, it can contain metadata and this could even be external data. All of the normal options with content types apply, so some very cool combinations can be made. One can choose which of the metadata of the document set should be shared with the documents residing in it. Document sets can also fully utilize the new Managed Meta data service. 

Document Set Welcome Page
Document Set Welcome Page

Default content 

When opening a document set, the welcome page of the set is shown. This shows the properties we have configured to be shown on the welcome page, as well as a list of the documents residing in the set. One of the things we can do with a document set is configuring that the set should be populated with default content (documents) upon creation. If we then assign document templates to the content types that should be created by default, we can easily set up a complete project repository including templates with just a click of a button! How cool is that! 

Document Set Settings
Document Set Settings

Unique ID 

Just like documents can receive a unique identifier when created, so can document sets. When enabled on the site collection, document sets receive a unique identifier just like normal documents. This ensures that the set can be found through the /_layouts/docidredir.aspx page at any time, regardless of its location within the site collection. 

Document Set Properties windows
Document Set Properties

Search 

Remember that I mentioned you could share (or inherit) document set metadata on the documents residing in the document set? This also shows in the search experience. When searching on a term that is a property of the document set, the documents residing in that set are also returned, along with the set itself. For example, I created a document set for a department in my team site and added a property on the set called Department. I shared that property with all the documents in the set by setting it in the document set settings and voila: all documents in the set can now also be found through the contents of the department property, for example procurement.

Search Results
Search result

Linking 

One of the limitations is that a document set can only contain documents that reside in the same document library, because of the folder like resemblance. One of the practical uses I thought of was creating case based sets using documents stored in different document libraries (or even sites), like within large organizations where multiple departments work together on a single case. If we edit the document set content type to allow the Link to Document content type, we can add links to documents residing in different libraries within the site collection (or even outside). If we also utilize the unique document ID link to the document, that document could even be moved and still found. And the coolest part? The linked document inherits the properties by the set, so that it can be found through Search! Clicking on the search result automatically redirects to the correct location of the document

Search Result with Link to Document
Search Result with Link to Document

Limitations 

There are some limitations though, unfortunately. For instance, it is not possible to add another document set in a document set, removing the possibility of nesting. Secondly, it is also not possible to add folders to a document set, although reversely, document sets could be added to folders. This prevents project like folder structures within a document set, for example large case based repositories. Also, document sets cannot contain documents that reside in other document libraries. They are physically bound to the same location. Final remarks, in earlier versions (betas), it was possible to to download multiple documents and documents sets as a zip file. In the RC and the final version, this functionality is skipped unfortunately.  

But without any doubt, it is a good step in the right direction! 

Have fun playing around with this!

The Unique Document ID feature

Enjoyed some time off due to the birth of my 3rd child Emma and finally found some time to get away from the diapers and constant nursering. 😉 And what a time to be back.

SharePoint Server 2010 is almost RTM, so an in-depth investigation of this new version of one the most important Microsoft products is long overdue.

In the following blog posts, I will review some of the new features of SharePoint Server 2010. Targeted far more at the Enterprise, SharePoint Server 2010 aims to remove some of the headaches that SharePoint 2007 had for both end users and developers, while maintaining its basic power, easy information sharing.

SharePoint Server 2010 introduces a lot of new features and functionalities. Some of them are improvements of existing functionality, some are completely new. Clear from a first glance though is that SharePoint Server 2010 has grown up and matured. Enhancements and new features make the new version far more scalable in large enterprises, one of the shortcomings of SharePoint 2007.

Unique Document ID feature

When using SharePoint as a document management solution, one of the shortcomings of SharePoint 2007 was the absence of a unique identifier for the document, regardless of its location. Sure, beneath the service, SharePoint 2007 did assign a GUID (Global Unique Identifier) to a document upon upload or creation, but there were no means to retrieve a document based on this GUID if you did not now the document library it was located in.

While SharePoint 2007 focused on libraries and lists, SharePoint 2010 moves more to sites (collections) and site pages. Several enhancements allow the site collection to share its information across the sites located in the collection.

The Unique Document ID feature can be enabled on site collection level, using site collection features. Once enabled, all documents placed within document libraries on the site collection will also receive a unique identifier field containing the ID of the document.

Based on search

The lookup of documents based on their ID is based on the Search functionality of SharePoint. First, the runtime will call the search provider to find the document. If search returns no documents, the provider calls a custom method for an alternative lookup. Because of the search dependency, when you move a document, it will not be found based on his ID unitl the next incremental crawl. Definitly something to take into account.

Configurable

When enabling the unique ID feature, we can also influence the way SharePoint assigns these unique identifiers. Unfortunately, these options are quite limited, as we can also specify text that each identifier should start with. However, because of the site collection scope, this problem is to overcome.

If you do not feel comfortable with the way SharePoint generates the ID’s, or you have specific rules or conventions to follow when generating these ID’s, it is good to know that you can create your own document ID provider. The way to do this is to create a subclass of the Microsoft.Office.DocumentManagement.DocumentIdProvider class and implement his methods. You can also specify that you want your own lookup method to be to called first, instead of the search. Using a site collection feature receiver, you can hook up this custom provider to the site collection by calling

DocumentId.SetProvider(properties.Feature.Parent as SPSite,new MyNewAndImprovedDocumentIdProvider());

Sending links

So, each document now haves a unique ID. Great, so how can we utilize that? When viewing the properties of a document now, you will find an additional field Document ID containing the unique ID of the document. This is also a link, pointing to the unique document ID service that can look up the document.

The link points to an aspx page located in the layouts folder called DocIdRedir.aspx. To recover a document based on the ID, just call http://yoursite/_layouts/DocIdRedir.aspx?ID=documentID
Interesting though is that when you press the Send a link button, the mail containing the link still contains the original url, pointing to the current location of the document. Obviously, when moving the document, the link would not be valid anymore.

The Ribbon

With SharePoint 2010, the ribbon is introduced in the online suite space. The ribbon and its contents will be subject for discussion in another blog post, but interesting now is that we can modify the ribbon items. We can therefore include a button that also send a link, but sends the permanent link, rather than the original one. I would have expected such a button to be there by default, but hey, we also need some work don’t we?

Till next time.

How to use assembly redirection in WSP’s

This article was posted on my previous blog located at http://blog.avanadeadvisor.com/blogs/patrick_boom in February. I moved it here.

Assembly redirection, a technique already introduced and available since the first versions of the .NET framework, is in my opinion not widely used in our line of work.
Sure, product suppliers like Microsoft itself use it frequently during updates, but somehow I have not come across this too often in my career.

To explain the concept of assembly redirection is a little bit beyond the scope of this blog, but I would like to elaborate on using this when using it with SharePoint 2007 WSP’s.

In large projects, especially with a lot of users in an already live environment, executing updates on the platform should be done with care and clear preparation. This is even truer when the update at hand involves shared frameworks, which multiple other projects use and you do not have direct control over. Of course, one could update the component without changing its version number and strong name, but this would not be very good practice, as version management and maintenance become much harder, if not impossible. The answer, of course, is assembly redirection.

Assembly redirection involves a technique to forward a particular method call to another assembly at runtime. For example, an application is bound to version 1.0.0.0 of your component. When updating, you increment the version number to 1.1.0.0. When published, the application will still use version 1.0.0.0 of the assembly if it is still available. If not, it will break. Using assembly redirection, you can forward the call to your 1.1.0.0 version and even remove the 1.0.0.0 version. This would automatically upgrade any application that referenced it and in the process, you make sure the latest version is used.

One very important aspect of this method, is that you have to ensure, no guarantee, that you are backwards compatible.  Not doing this is bound to introduce problems. Secondly, you should not change the definition of the method in doing something completely different than its original scope, which could lead to unexpected behavior of its clients.

That said, how does this relate to SharePoint 2007? Well, suppose I have a SharePoint middleware layer that executes various common functions, on top of which SharePoint application are build. Using good practice, I publish this layer to the SharePoint platform using a WSP (or multiple), which in turn configures SharePoint (for example the SafeControls) and publishes the assemblies to the Global Assembly Cache. When time passes, I would like to update the framework by introducing new features (which would lead to a version increment) and bug fixes. I would then publish an updated WSP, which will retract the old one (and thus removing the configuration and the assemblies from the GAC) and install the new one. Doing this without assembly redirection will break all applications that reference the assemblies.

Ok, so, just include an assembly redirection policy, you think. That is where the trouble starts. To install an assembly redirection policy in the GAC, you need to convert it into an assembly, as the GAC only accepts assemblies. There are many articles on the internet that describe how to create such an assembly, so I will not go into that here. I use, like many others, WSP Builder (or its Visual Studio Extension) to create my WSP’s. If I include the policy assemblies in the GAC folder, WSP builder will also package that. Well, so far so good. When I install this WSP into SharePoint, it will result in an error, stating that the policy assemblies could not be published into the GAC. This is caused by a simple caveat in using policy assemblies. Because they are not ‘real’ assemblies in the true sense of the word, they are only allowed to be published to the GAC, if the original configuration file that was used to create the assembly, is located in the same directory. And the WSP omits this file. The current version of WSP builder does not include .config files when packaging, even if they are located in the same directory.

There are several ways in solving this problem. You could create your WSP manually, be writing the correct DDL that does includes the config files in the root of the WSP. You could modify WSP builder (as it is open source) to include these config files in the root of the WSP. I however, choose the outside approach. As a WSP is just a cabinet file with a different extension, I created a small app that uses cablib.dll (just like WSP Builder) to modify the created wsp and insert the config files at the root. This has two advantages:

  1. The config files are only needed during install, so using this method would avoid the config files being included in the manifest.xml and therefore permanently stored on the file system.
  2. I can choose whether or not to include the config files, or even update them afterwards, without rebuilding the WSP.

After this, the WSP installs just fine and the policy assemblies are included in the GAC, ensuring proper rerouting of method calls to old assemblies, therefore automatically upgrading any dependent applications in the SharePoint landscape.

A couple of final notes on the redirection part:

  1. Create one policy assembly for each version you wish to reroute. You cannot reroute multiple versions from within a single policy assembly.
  2. The naming of the policy redirection assembly is very strict and follows naming conventions. Not following these conventions will result in your assembly not being redirected.
    policy.<major>.<minor>.<assembly name>.dll
  3. Ensure that you only use the major and minor versions in the AssemblyVersion attribute. Build and revision numbers should never be included in the AssemblyVersion attribute, but in the AssemblyFileVersion attribute. For example:
    AssemblyVersion 1.0.0.0, AssemblyFileVersion 1.0.010043.0 (day 43 in the year 2010)
    AssemblyVersion 2.1.0.0, AssemblyFileVersion 2.1.010043.1

Assembly references are made using the AssemblyVersion attribute, thus giving you the possibility to publish bug fixes (which only increment the build and revision numbers), without the need for a policy redirection assembly.

Hope this can be of use to you. Let me know your thoughts! Any comments are appreciated.

How to add the quick launch to the default Web Part Page templates

This article was published on my previous blog located at http://blog.avanadeadvisor.com/blogs/patrick_boom in January. I moved it here.

One day, one of our end-users raised the question why the quick launch navigation bar was not visible when adding a new page to an existing site. The user chose the Web Part Page in the Create menu to create a new web part page on the site. After creation, the new page did not show the quick launch bar.

 When diving into the issue, indeed, the standard out-of-the-box page templates (8 templates) do not include this bar. To me, this was quite strange, as I could not think of any reason why this would be desired. Nevertheless, when researching the page templates, the default templates override the master page to omit the quick launch navigation bar. And so, the journey to have them added begins.

 How are the standard Web Part Page templates called and referenced?

Upon first research I found that the standard 8 templates are hard referenced in a page called spcf.aspx by the create.aspx page. The create.aspx page is the page shown when clicking Create from the Site Settings menu. The Web Part Page option points to a file called spcf.aspx which shows the New Web Page dialog that includes the page layout selection. On this page, 8 page layout options are available by default, dividing the available space in several web part zones in different layouts. The available templates are hardcoded in this page.

 Possible approaches

There are several approaches one could take in solving this. For example:

1.       Locate the standard page templates on disk and modify them

This involves opening the standard page templates in an editor like Visual Studio, look up the overrides off the content placeholder where the quick launch navigation bar resides in the master page and remove them.

2.       Keep the existing page templates, but make copies

This involves copying the existing page templates, rename them and then edit them and remove the overrides. Disadvantage would be that we have to change the spcf.aspx page to reference the new templates instead of the standard ones, as these are hard-coded.

3.       Keep existing page templates and spcf.aspx, but make copies

Same approach as option 2, but also copying the spcf.aspx page and rename it. This would introduce another disadvantage that we have to change the create.aspx as the spcf.aspx is hard referenced in there.

Several other approaches using Javascript on the client with iframes are also an option, but I was looking for a neat solution on the server, without using Javascript. All of these options involve changing default out-of-the-box files of SharePoint, which could lead to problems when applying service packs or hot fixes, as well could cause limited support on the standard installation by Microsoft. Option 3 is described by Paul Papanek in his blog found here: http://mindsharpblogs.com/pauls/archive/2008/08/19/7488.aspx

 How to do it without changing any of the standard SharePoint files?

At my current customer, we have several restrictions when applying modifications to the SharePoint landscape. First, none of the out-of-the-box files are allowed to be touched. Secondly, any modifications to the system must be done through a feature packaged in a WSP.

These restrictions rule out all the approaches described above. Secondly, it removes the possibility for creating Web Part Pages without the navigation, for which there could be valid reasons. I have found a way to include them, without touching the OOB files and still honoring the restrictions I had. To be fair though, it is a mere extension of the approach that Paul describes in his blog, so also credits to him. Now, without further due, let us continue to the solution.

 THE SOLUTION

There are several steps that need to be taken, which I will describe in detail below. Let us first outline the steps:

1.       Create a new Visual Studio empty solution that will host your new feature.

2.       Copy the standard page templates and rename them

3.       Edit the renamed templates to include the quick launch again

4.       Save the preview images for all the standard templates to a location which you can find later

5.       Create a new spcf.spx page based on the standard one and modify it to reference the new layouts

6.       Create an additional menu option on the Create page to point to your new spcf.aspx page

7.       Package all the files into a feature

8.       Package the feature in a WSP

 Create a new Visual Studio empty project that will host your new feature

Within Visual Studio, create a new empty project to host your new feature. You can use any project type you are accustomed with to create SharePoint features, I just use an empty project. I also use the WSPBuilder extensions to create a WSP, but creating the WSP is out of scope of this blog.

Within your project, create a folder structure to represent your 12 hyve that includes all the locations where we will deploy files, as shown in the attachement PageLayouts Image 1.png
 

Copy the standard page templates and rename them

The standard Web Page Page Layouts are located in the 12\Templates\1033\STS\DOCTEMP\SMARTPGS directory, where 1033 stands for English. If you have another language version installed, please replace 1033 with the language identifier installed.

In there, you will find 9 files, of which 8 are aspx pages, called spstd1.aspx through to spstd8.aspx. Make a copy of these files and include them in your project in the same folder. Make sure you rename them to any name you wish, but keep the number suffix, for example, avanade1.aspx.

 

Edit the renamed templates to include the quick launch again

Open each file in Visual Studio and remove the following lines to add the quick launch again:

asp:Content ContentPlaceHolderId=”PlaceHolderLeftNavBar” runat=”server”>asp:Content>

asp:Content ContentPlaceHolderId=”PlaceHolderNavSpacer” runat=”server”>asp:Content>

Save and close each file.

 

Save the preview images for all the standard templates

To preserve the preview image for each page template, we copy the preview images for each template to our solution. The preview images are located at 12/TEMPLATES/LAYOUTS/1033/IMAGES and are called SPSTD1.gif to SPSTD8.GIF. Rename the images to the same name used for the templates in previous steps, for example avanade1.gif.

 

Create a new spcf.aspx page based on the standard one and modify it to reference the new layouts

 Paul Papanek included a custspcf.aspx on his blog that also removes the limitation of 8 templates, as the current 2007 implementation of spcf.aspx does. It is therefore recommended to use the one provided by Paul as the basis. You can download it from here http://www.dontpapanic.com/download/custspcf.aspx.txt. You can also copy the existing one from 12/TEMPLATES/LAYOUTS/1033, where again, 1033 is your language identifier.

 Include the file in your project and open it in the editor. You may rename the file to any name you want, I just use custspcf.aspx to keep the relationship to spcf.aspx intact. There are a couple of things that you need to change in this file to make it work with your newly created template and images. Do a search on ‘custom1’ and replace all the references to this with the name of your own custom templates, in our example I would replace ‘custom1’ with ‘avanade1’ and so on. 

Also find the

 SELECT id=”onetidWebPartPageTemplate” name=”WebPartPageTemplate” size=”2″ onchange=”DoTemplateOptionChange()”>

 tag, which includes all the possible template options. In the file downloaded from Paul, only two exist. If you take the one from the original spcf.aspx, you will find 8 options.  Modify the ‘size’ attribute to reflect the number of copied templates, in our case 8. I added the options exactly as they were in the original file, just renamed the template names, as shown below:

 SELECT id=”onetidWebPartPageTemplate” name=”WebPartPageTemplate” size=”8″ onchange=”DoTemplateOptionChange()”>

  OPTION value=”avanade1″>Full Page, VerticalOPTION>

  OPTION value=”avanade3″>Header, Left Column, BodyOPTION>

  OPTION value=”avanade4″>Header, Right Column, BodyOPTION>

  OPTION value=”avanade2″ selected=”true”>Header, Footer, 3 ColumnsOPTION>

  OPTION value=”avanade5″>Header, Footer, 2 Columns, 4 RowsOPTION>

  OPTION value=”avanade6″>Header, Footer, 4 Columns, Top RowOPTION>

  OPTION value=”avanade7″>Left Column, Header, Footer, Top Row, 3 ColumnsOPTION>

  OPTION value=”avanade8″>Right Column, Header, Footer, Top Row, 3 ColumnsOPTION>

SELECT>

 In fact, most of the work is now done. The only thing left is ensure that we can call our new pages from the Create page in the SharePoint UI.

Create an additional menu option on the Create page to point to your new spcf.aspx page

Most menus in SharePoint can be extended with custom actions, like context menus, the Site Actions and so on. This is because these menus also use the FeatureLinks feature that allows additions to this menu. We will use this to add our custom option to the Create page.

Create a feature.xml within our feature folder in our solution, in my case called Avanade.PageLayouts.  The contents of the feature.xml is shown below:

<?xml version=”1.0″ encoding=”utf-8″?>
<Feature 
  Id=”ECBCD0E9-C2B3-4dc0-A6B8-63846000CB83″
  ImageUrl=”avanade.gif”
  Title=”Avanade – Custom Web Pages Menu Option”
  Description=”Enables a custom menu item for creating Web Part Pages with quick Launch navigation.”
  Version=”12.0.0.0″
  ActivateOnDefault=”FALSE”
  Scope=”Farm”
  Hidden=”FALSE”
  DefaultResourceFile=”core”
  xmlns=”http://schemas.microsoft.com/sharepoint/“>
  <ElementManifests>
    <ElementManifest Location=”CustomWebPages.xml” />
  </ElementManifests>
</Feature>

The feature refers to an ElementManifest called CustomWebPages.xml which will include the menu option. In my case, I scoped the feature to Farm, enabling the custom templates across all sites in the Farm. You can use WebApplication, Site or Web scope if desired.

The contents of CustomWebPages.xml is shown below.

<xml version=”1.0″ encoding=”utf-8″?>
<Elements xmlns=”http://schemas.microsoft.com/sharepoint/“>
  <CustomAction
        Id=”CustomWebPageSettings”
        Title=”Web Part Page with Quick Launch”
        Description=”Create a Web Part Page with quick launch navigation”
        Location=”Microsoft.SharePoint.Create”
        GroupId=”WebPages”>
    <UrlAction Url=”_layouts/custspcf.aspx” />
  </CustomAction>
</Elements>

 Within this file, we define a custom action with the following attributes:

Id: Identifies your custom action
Title: Is shown in the user interface as the menu option
Description: Is shown on top of the page as description of the menu option
Location: Determines the location (page) to apply the custom action on. In our case, this refers to the Microsoft.SharePoint.Create location, which is the Create.aspx page.
GroupId: Identifies the menu (column) to add the option to, in our case the ‘WebPages’ column.
UrlAction: Identifies the page called when clicking the menu option, in our case, this should point to our newly created custspcf.aspx page, which completes the circle.

 That’s it! Only thing left is to package the feature into a WSP to facilitate easy distribution and installation. If you do not use a WSP, you should also include an ElementManifest to deploy the different files to their location. When creating a WSP from this folder structure, WSPBuilder will take care of the deployment of the files for you.

I hope this could be of use to you.  Happy coding!