The scenario is the following: Version one of a WebPart is developed and deployed to the SharePoint farm using Solution Deployment. The solution Manifest.xml contains the assembly reference to deploy the assembly to GlobalAssemblyCache and further more the SafeControl definition.
When deploying the solution, the assembly will be placed in the GAC and a SafeControl entry will be written to the web.config files of the selected WebApplications. You are now ready to create the WebPart definition and start using the little wonder.
The way SharePoint now loads your WebPart (very simplified) is like this. SharePoint reads the WebPart definition on the page. It the checks if this WebPart is registered in the SafeControl entries for the page. If this is true it loads the assembly and displays the page.
After a while you realize that you made something (by design of course) that the users are not happy with and you need to change the code. During this upgrade you decide to change the version number of the assembly to 22.214.171.124. As the smart clever developer you are, you remember to include a publisher policy file that points request from the old version to version 2. The new WebPart is repackaged in the solution together with the compiled policy file and you upgrade it on the server, but when the users access the site with the updated WebPart, they will receive an error message saying that a WebPart on the page is not registered as safe.
The reason for this is that during the upgrade of the solution, the SafeControl entry was changed to v126.96.36.199 to reflect the new assembly version. When the user opens the page, the WebPart definition on the page still point on the first version and when SharePoint checks whether this WebPart is defined in the SafeControl entries, it will return false and thus SharePoint will throw the exception mentioned previously.
Ahaaa, you might think, then I can just add SafeControl entries for both version one and two in the Manifest file, but unfortunately the solution deploy job will override this and only deploy the latest version.
So what can you do about this?
1. Do not version your WebPart assemblies - use AssemblyFileVersion instead.
2. Create a Feature, that contains a Callout which uses the SPWebConfigModification object to add the SafeControl entry for the old assembly version. You can find examples on using SPWebConfigModification by searching for it on the world wide web :o)
When both SafeControl entries are added to the web.config then when the users access the page for the first time, the site will try to load version 1 and after clearing through the SafeControl layer it will hit the policy file and load version 2. Furthermore the WebPart definition on the page will be updated to version 2.