This post was migrated from an older system. Some links may point to content that no longer exists. Comments were not migrated.
When it comes to updating a Web Part, what is the first thing that comes to mind when someone mentioned the version #?
Keep it at version 184.108.40.206 (or whatever value you initially used).
Now, let me ask you two questions...
- Did you know that you can use .NET framework's assembly binding redirection to change from version X to version Y?
- Did you know that it works in SharePoint 2007?
That's right, you can upgrade Web Parts in SP 2007 using bindingRedirect tags!
It works like a champ.
Unfortunately, there's a few problems:
- Most people don't realize assembly redirection works with Web Parts
- Most people don't really know how to make it fully work for Web Parts in SharePoint
- It required some level of custom/manual effort to make it work.
As for problem #3, the only way to programmatically do it in SharePoint 2007 was to use the SPWebModification class. Well, that is a whole other set of pains that most folks tend to avoid. Most developers probably avoided that class due the various bugs in that area.
In short, bindingRedirect was a long lost and forgotten feature in SP2007.
Well, in SharePoint 2010 that story changes!
You can now EASILY define assembly redirection via your solution package.
By adding a <BindingRedirects> element to an <Assembly> node, problem #3 goes away.
<Assembly Location="Bluedoglimited.Demo.WebParts.dll" DeploymentTarget="GlobalAssemblyCache">
It's even super easy to implement using VS 2010's manifest merge functionality.
Sweet. We can effectively call problem #3 solved!!
However, we still have problem #2. You need to give SharePoint some information on how to handle the instances of version X that live throughout your SharePoint site. In short, we need to figure out how to get past problem #2.
Configuration Requirement: In order for redirection to work for your Web Parts in SharePoint you need to include the SafeControl information for your old versions that you wish to upgrade. Otherwise, your old version X will never have a chance to upgrade to version Y.
Now... that's easy enough to do. But why?
What happens to your Web Part when it's redirected to version Y?
- On first render of a redirected Web Part instance (this is a KEY thing to remember), if the SafeControl for version X exists, an attempt to load the Web Part is made.
- The .NET framework kicks in and redirect to version Y is successfully made.
- SharePoint notices that the Web Part type guid (nothing we the Web Part developers can explicitly control) has changed and saves the new type id back to the database.
- From that point forward, the next time the Web Part is loaded, the call is made directly for version Y.
Take a look at step #3. This is key. The database actually contains a reference to your web part in a form of a guid. The guid is a calculated value that allows the SafeMode parser to rapidly associate the serialized form with a live class type. The important thing to remember is that this reference lives on a per-page reference (i.e. page ABC has reference to web part types M, Q, V).
Why is this important? Until all instances of Web Part version X have been rendered, you cannot remove the SafeControl reference to version X unless you want bindingRedirect to fail.
Operational Requirement: Keep SafeControl entries for old versions around until all Web Part instances have been rendered.
If you don't assembly redirection can't be completed and redirection appears to have failed (when technically it never had a chance to start!). This requirement remains unchanged for 2010.
Ok... that's cool. Keep old SafeControls entries around until we know all instances have been "upgraded".
Summary: The logic and requirements are basically unchanged in 2010 when it comes to assembly redirection for Web Parts. However, thanks to SharePoint 2010's new functionality, you can easily include directions via your solution file. No need to mess around with clunky SPWebModification changes or manual web.config updates.
There's one slight problem with the 2010 feature, though.
There's a bug in the deployment code that generates the public key token for the publicKeyToken attribute. I'll discuss that in my next post...