kamagra how much to take

SharePoint WebPart Versioning

WebPart versioning is a discussion that I have with clients, as well as internally, consistently. Largely this is because it can hit sensitive organizational points (if they have a reasonable software development initiative) and is terribly prone to developer opinion. It can rapidly move from a pragmatic to esoteric discussion.

For these reasons, it is challenging to structure a best practice regarding WebPart versioning, since there really is no best practice. However, after presenting some options I think it is reasonable to assume that an organizational best practice can be cultivated and everyone can be happy.

To try to get those gears turning, I am going to fly through at a 10,000 foot view of various problems typically encountered when implementing a WebPart versioning strategy, some approaches, and a base class that I use that leverages one of the discussed version approaches using a display vehicle I like the most.

Before I continue, let me state that the remainder of this post is going to assume strong named/signed assemblies, as well, these assemblies are being stored in the GAC.

Problems with Versioning

Arguably, the most difficult segment to tackle when dealing with WebPart versioning is that the AssemblyVersion attribute tends to be of little use because WebParts can be considered to use static versioning. AssemblyVersion within orthodox managed development tends to be heavily leveraged because it defines an integral number regarding the assembly’s identity. So, why is the AssemblyVersion such an ineffective mechanism to rely on when dealing with SharePoint WebPart development?
There are three main reasons:

Referencing the AssemblyVersion attribute, as managed assemblies in the GAC do, will break if this value changes.

The SharePoint WebPart Description File (.webpart or .dwp) references the AssemblyVersion attribute within the type element in its XML structure. This element consists of a string with type and assembly information about the corresponding webPart element. As a result, any description files already instantiated on a page won’t bind right due to an incorrect assembly version number.

Without modifying the safe controls entries for the SharePoint site, there will be an assembly mismatch when altering the AssemblyVersion number, resulting in a safe control error when attempting to render the WebPart (if already on a page, otherwise it won’t be allowed on the WebPartPage). This can be solved with solution redeployment or manual web.config modifications; however you are following still subject to the same problem as described above so while fixable, isn’t a rational solution.

There are some more issues, most I consider negligible so I won’t go over them; however those are the largest ones.

Versioning Storage

In order to resolve not having a dependency on the AssemblyVersion, a margin of people rely on the AssemblyFileVersion attribute since this can arbitrarily change with little effect on the WebPart. Use of this also provides the same experience as using the AssemblyFileVersion since this value is mutable from VS.NET with nearly the same invocation. As well, for people that are using Reflection in order to hydrate objects with the relevant assembly information, the mechanics are consistent once you have an Assembly object.

Otherwise, static string representation is simple and popular. This involves setting the values of the version and build name within the assembly, a satellite assembly, or from some other arbitrary source. It could be a wide range of objects, even from a tabulated text file, it doesn’t really matter. All that matters is that the version information is read from a source, and that source is not the calling assembly.

Choosing a Display Vehicle

The display mechanisms for versioning vary depending on the organization. I have seen in the majority of projects these four major types:

Toggle the corresponding SharePoint Feature description element prior to the SharePoint solution packaging.

Just format and dump it out to directly out to standard output as part of the control.

Add a new WebPartVerb object to the current instance WebPartVerbCollection with the version information.

Add a new EditorPart to the current instance EditorPartCollection with the version information

Making It Work

As an example, I am going to use the last option, and place my versioning information in an EditorPart object. In order to consistently enforce this across multiple WebPart type projects, a new base WebPart class for subclass use will be defined which contains all the relevant code to handle the versioning. In order to pass unique values for the program name and the version number, the derived class constructor will be used. The approach is similar to using the WebPartVerb approach, and could easily be ported over to that construct if EditorPart¬† objects don’t really blow your back.

To do this, three different classes are used. VersionInfo contains a static method that renders to standard output the required strings using strongly typed formatting objects. EditorVersionPart inherits from the EditorPart class, and contains two backing fields that are toggled in the constructor. EditorVersionPart calls the static VersionInfo.CreateVersion method to build out the visual representation of the version information. The WebPartBase class inherits from the WebPart, and IWebEditable interface. Regarding the latter of these, its type members are implemented, which call the custom EditorVersionPart class.

As a result of using this class, you will be presented with the following when using it as your base class, demonstrated in a trivial WebPart.

In order to provide the required strings, in the WebPart constructor the desired values are being provided.

As a result, the WebPart class structure will take on the following form:

  1. namespace buenz.SharePoint.WebParts
  2. {
  3. public class VersionDemo : WebPartBase
  4. {
  5. public VersionDemo()
  6. {
  7. _name = "My WebPart";
  8. _version = "1.0.0.0 (Debug / Checked)";
  9. }
  10. }
  11. }

And the related classes to achieve this effect are:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Web.UI;
  4. using System.Web.UI.WebControls;
  5. using System.Web.UI.WebControls.WebParts;
  6. using Microsoft.SharePoint;
  7. using midwave.SharePoint.WebParts;
  8.  
  9. namespace buenz.SharePoint.WebParts
  10. {
  11. public class VersionInfo
  12. {
  13. public static void CreateVersionSegement(HtmlTextWriter writer, string version, string name)
  14. {
  15. var tbl = new Table {HorizontalAlign = HorizontalAlign.Center};
  16. var row = new TableRow {HorizontalAlign = HorizontalAlign.Center};
  17. var versionRow = new TableRow {HorizontalAlign = HorizontalAlign.Center};
  18. var cell = new TableCell {HorizontalAlign = HorizontalAlign.Center, Text = string.Format("{0}", name)};
  19. var versionCell = new TableCell {HorizontalAlign = HorizontalAlign.Center, Text = string.Format("{0}", version)};
  20. row.Cells.Add(cell);
  21. versionRow.Cells.Add(versionCell);
  22. tbl.Rows.Add(row);
  23. tbl.Rows.Add(versionRow);
  24. tbl.RenderControl(writer);
  25. }
  26. }
  27. }
  28.  
  29. public class EditorVersionPart : EditorPart
  30. {
  31. public string _name;
  32. public string _version;
  33.  
  34. public EditorVersionPart(string webPartID, string name, string version)
  35. {
  36. Title = "WebPart Versioning";
  37. ID = string.Format("MyEditorPart{0}", webPartID);
  38. _name = name;
  39. _version = version;
  40. }
  41.  
  42. protected override void RenderContents(HtmlTextWriter writer)
  43. {
  44. base.RenderContents(writer);
  45. VersionInfo.CreateVersionSegement(writer, _version, _name);
  46. }
  47.  
  48. public override bool ApplyChanges()
  49. {
  50. EnsureChildControls();
  51. return true;
  52. }
  53.  
  54. public override void SyncChanges()
  55. {
  56. EnsureChildControls();
  57. }
  58. }
  59.  
  60. public class WebPartBase : WebPart, IWebEditable
  61. {
  62. public string _name;
  63. public string _version;
  64.  
  65. EditorPartCollection IWebEditable.CreateEditorParts()
  66. {
  67. var editors = new List<EditorPart> {new EditorVersionPart(ID, _name, _version)};
  68. return new EditorPartCollection(editors);
  69. }
  70.  
  71. object IWebEditable.WebBrowsableObject
  72. {
  73. get { return this; }
  74. }
  75. }
  76.  
  77. }

Happy Versioning! :)

Share

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>