I’ve seen lots of Sharepoint software having an installation manual of at least 20 pages (sometimes 60). Most of the operations they describe could be fully automated. And these software were made by freaking big companies. They should be ashamed of themselves. Maybe they just forgot that computer science is all about saving some time (and not only making money).

One good example is MOSS Faceted search 2.5 (I haven’t tested the 3.0). It takes at least 40 minutes to uninstall this crap. Why isn’t it just ONE WSP or at least one BAT file launching the WSP installation and the other steps ? Is there any real reason for that ?

The SPWebConfigModification solves this web.config modification problem. It’s a pretty interesting feature of Sharepoint. You can edit the web.config file without any complex XML parsing. It doesn’t even matter that you add XML or not. The SPWebConfigModification class manages your add/mod/del operations easily. The only restriction is that you have to add your first configuration elements using the SPWebConfigModification. You cannot modify existing elements this way.

// Source : http://sharethelearning.blogspot.com/2008/01/adding-bindingredirect-to-webconfig.html
public static void AddBindingRedirect( SPWebApplication webApp, string libraryName, string libraryPublicToken, string oldVersion, string newVersion ) {
    var ownerName = String.Format( "BindingRedirect.{0}", libraryName );
    { // We delete last bindingRedirect
        var list = new List<SPWebConfigModification>();
        foreach ( SPWebConfigModification mod in webApp.WebConfigModifications ) {
            list.Add( mod );
        foreach ( var mod in list ) {
            if ( mod.Owner == ownerName ) {
                LoggerCommon.LogVerbose( String.Format( "Deleting: \"{0}\"", mod.Value ) );
                webApp.WebConfigModifications.Remove( mod );
    { // We add our redirection
        String path = "configuration/runtime/*[namespace-uri()='urn:schemas-microsoft-com:asm.v1' and local-name()='assemblyBinding']";
        String name = String.Format( "*[namespace-uri()='urn:schemas-microsoft-com:asm.v1' and local-name()='dependentAssembly']/*[namespace-uri()='urn:schemas-microsoft-com:asm.v1' and local-name()='assemblyIdentity'][@name='{0}']/parent::*", libraryName );
        String webConfigValue = String.Format( @"
        <!-- Added automatically at {4} -->
        <assemblyIdentity name='{0}' publicKeyToken='{1}' culture='neutral' />
        <bindingRedirect oldVersion='{2}' newVersion='{3}' />
", libraryName, libraryPublicToken, oldVersion, newVersion, DateTime.Now );
        SPWebConfigModification mod = new SPWebConfigModification( name, path );
        mod.Value = webConfigValue;
        mod.Owner = ownerName;
        mod.Sequence = ;
        mod.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
        webApp.WebConfigModifications.Add( mod );
    { // We save our changes

If you do a binding redirect from to and your .webpart file references the version, sharepoint will store your webpart as referencing the assembly (and not as you told him). So if you then chose to change the binding redirect from to, without redirecting to, your webpart will still be the version.

I haven’t tested this for event receivers, but the way they are registered (Sharepoint doesn’t check the assembly you add to the event receivers of a list), I would guess Sharepoint doesn’t change the assembly version.

To solve this webpart updating problem, you can use ranged binding redirect (.Net rules) :

var site = new SPSite("http://localhost");
AddBindingRedirect( site.WebApplication, "MyCorp.MyApp.MyLib", "0x123456789", "", "" );

That means that any webpart using a previous version of the MyCorp.MyApp.MyLib assembly between and will be redirected to the version.

If your assembly contains page code-behind classes, you should take care of updating the aspx files as well.