Logo SharePoint Thoughts   Downloads   About   Up to Bluedog Limited
Handling unknown properties during a Web Part upgrade
Posted on 5/11/2010 11:45 AM by Maurice Prather
One of the classic problems with Web Parts is dealing with properties as your Web Part evolves and some properties are no longer needed.
Scenario:
Imagine that today you create a Web Part with property A.  You deploy the part and everything is working as expected. 
 
Then next week, you come along and decide that property A is no longer good enough.  You decide that your Web Part should have property B instead of A, but you need to use some information previously recorded in A. 
How do you deal with "upgrading" your properties?  WSS Web Parts and ASP.NET Web Parts both offer mechanisms you can use to easily interrogate older, unknown properties. 
  • In WSS Web Parts, you can reference the UnknownXmlElements property.  This property contains, as the name implies, all of the unknown xml elements found in the serialized form of that web part instance.
  • In ASP.NET Web Parts, you need to use the IVersioningPersonalizable interface.  This interface will allow you to process any orphaned personalization data. 

Interestingly enough, it's come to my attention that a lot of folks have never heard about IVersioningPersonalizable. It's handy, so be sure to put it into your toolbox.  :)

To help you along, here's an IVersioningPersonalizable example that you can easily test...

public class WebPart1 : WebPart, IVersioningPersonalizable {

  //[WebBrowsable]
  //[Personalizable(PersonalizationScope.Shared)]
  //public string OriginalValue { get; set; }

  [WebBrowsable]
  [
Personalizable(PersonalizationScope.Shared)]
  public string EvolvedValue { get; set; }

  private System.Collections.IDictionary orphanedProperties;

  public WebPart1 () {
    this.Init += new EventHandler(InitHandler);
  } // End of constructor

  /// <summary>
  /// If property sets have changed, this method is called by the framework
  /// </summary>
  /// <param name="unknownProperties">Collection of orphaned properties</param>
  public new void Load(System.Collections.IDictionary unknownProperties) {

    // ----------------------------------------------------------------------
    // Save the reference to a local property. 
    // ----------------------------------------------------------------------
    // NOTE: 
    // SharePoint's Web Part Manager has not completed the load sequence at this 
    // point in time; therefore, if you call SetPersonalizationDirty at this point
    // in the lifecycle, you will get an InvalidOperation exception stating there 
    // is no WebPartManager on the page.
    // ----------------------------------------------------------------------

    this.orphanedProperties =     unknownProperties;

  } // End of Load

  private void InitHandler(object sender, EventArgs e) {

    // Check to see if we need to handle orphaned properties...
    if (this.orphanedProperties == null) {
      return;
    }

    // Find the property we want to update...
    foreach (System.Collections.DictionaryEntry de in this.orphanedProperties) {

      this.Controls.Add(new LiteralControl(de.Key + ": " + de.Value + "<br/>"));

      // Let's save OriginalValue property into EvolvedProperty
      if (de.Key.ToString() == "OriginalValue") {

        this.EvolvedValue = "Updated: " + de.Value;
        this.SetPersonalizationDirty();

      }

    }

  } // End of InitHandler

} // End of WebPart1 class

To see IVersioningPersonalizable.Load in action, you will need to..

  1. Uncomment the OriginalValue property. Compile, deploy.  (leaving the EvolvedProperty in place is ok)
  2. Add the part to a page, then set the OriginalValue property to something (i.e. "my value")
  3. Comment out OriginalValue propertly. Complile, deploy.
  4. Visit the page once more.  You should now see a message that says "OriginalValue: my value".  If you were to view the property pane, you will see that EvolvedValue now contains "Updated: my value".

Both the WSS and ASP.NET methods for reviewing orphaned properties effectively operate in the same manner, but there is one key difference:

ASP.NET Web Parts will not persist the collection of orphaned data if the Web Part is modified before you have a chance to process the data.  WSS Web Parts, on the other hand, will persist orphaned property values until they have been explicitly removed.

In short, it's really easy for you to create Web Parts whose property sets are evolving.

-Maurice

No comments have been posted yet.
RSS feed
Microsoft Certified Master
MVP Logo
Follow me on Twitter!
Keyword Search
 
View by category
 

Disclaimer:
The contents of this site represent thoughts and opinions of the authors , not those of anyone else - such as past, present and future employers.  This a forum of the exchange of ideas centered on SharePoint technologies.  It is not a support channel.  :)

Copyright © 2004-2010 Maurice Prather, Inc. All rights reserved.