Friday, November 20, 2009

HtmlFilter - The ultimate SharePoint and .Net code hack

If you've ever run into a wall of closed classes or inaccessible functionality within asp.net or SharePoint, then I have good news for you. When you can't interface with out of the box server side objects, you can always fall back on the HtmlFilter to save you.

The code I wrote will allow you to intercept whatever HTML the server outputs to the browser and filter it via REGEX expressions returning whatever you would like. It works via the page.response.filter property.

You can add the filter at any point (before pre-render) in your server-side code.  This allows you to selectively apply filters based on server side code and to insert server-side parameters.
Warning: Regular Expressions will increase the server processor load.  Each page request implementng this tool will add some overhead as it searches the html.  You may need to load test your expressions and possibly optimize them.  Note that there is also a property that will bypass the filter on asynchronous page loads, although the performance hit of an asynchronous page load will already be reduced since only the updated html will be filtered.  On the other hand, the overhead on the server will probably be less than the overhead that would be created on the client and via increased content bandwidth if a javascript solution was used.

The HtmlFilter is now available on CodePlex.
Refer to the CodePlex project for future updates and usage examples.

Setup
  • Add the HtmlFilter.vb file to the App_Code\VBCode folder

    • See here for how to configure separate VBCode and CSCode folders using CodeSubdirectories in the web.config

Usage
  • In your UserControl or Page CodeBehind, add the following code in the Page_Load event handler

    • For VB

      Dim FilterReplaceValues As New Specialized.NameValueCollection
      FilterReplaceValues.Add("Your Regex Expression", "Your Replacement Expression")
      HtmlFilter.SetHtmlFilter(Page, FilterReplaceValues, 10000)
      

    • For C#

      Specialized.NameValueCollection FilterReplaceValues = new Specialized.NameValueCollection();
      FilterReplaceValues.Add("Your Regex Expression", "Your Replacement Expression");
      HtmlFilter.SetHtmlFilter(Page, FilterReplaceValues, 10000);


  • The number 10000 in the code above should be at least the length of any replaceable string.

    • This is used in the stream to reduce buffer size.
    • Example:  If you will be replacing strings up to 20 characters, you would put 20 or more there.

  • Fill in the appropriate Regex and Replacement expressions according to your needs.

    • You may add multiple FilterReplaceValues to the collection.  It will parse each one in order.
    • Examples (VB)

      • Remove all UserControl prepended Identifier strings from Form elements, for use in a custom cross-page post scenario.

        "(name|id)=""[^""]*" & Me.ID & "[\$_]", "$1="""

      • SharePoint: Remove the Edit and Export Web Part Edit items from the Edit Menu

        "(?s:<ie:menuitem type=""separator"" /><ie:menuitem title(?!.*separator.*id=""MSOMenu_Edit"").*MSOMenu_Edit.*Export\.\.\.(\r|\n|\s)*</ie:menuitem>)", ""



  • For help creating your own expressions, use some of these tools


SharePoint Backup and Migration Solutions - Third Party Tools

SharePoint Backup, Restore, and Migration are some of the biggest pains with maintaining SharePoint.
Here is a list of tools that have been developed to address some of the issues.  I will fill in details when and if I evaluate them.

Disaster Recovery (these may also support backup/restore migrations)
Migration
Or if you feel lucky, the out of the box stsadm Export and Backup commands can be used.
They should be supplemented with the following

Thursday, November 19, 2009

SharePoint 2007/3.0 Group By AJAX

Scenario
  • Modifying the SharePoint 2007 GroupBy functionality when groups are collapsed by default
  • HtmlFiltering content within one of the groups
  • Using HtmlFilter prior to 11/19/09 release
Issue
  • When expanding a group, the contents are messed up or never display  (loading ... )
  • This is caused by a strange implementation of AJAX on Group By fields within the SharePoint List Web Parts

    • Normally the UpdatePanel syntax is pipe-delimited with

      • length|???|???|content

        • The middle 2 parameters seem to be UpdateType and ID


    • But the SharePoint syntax is

      •  lengthOfEventValidationString|eventvalidationstringcontent||content
      • the second and third pipes || are located together between Icon="icgen.gif and " OType="0" within the table tag
      • ??? Let me know if you can think of any logic for this syntax ???


Resolution
  • Upgrade to the newest HtmlFilter.vb release which will account for the SharePoint Group By syntax

Fiddler was the key to fixing this bug.

Monday, November 16, 2009

Access Denied, Not a Site Collection Admin, and Cannot Create New Items

Scenario
  • You are a Site Collection Admin and Farm Admin for a SharePoint Farm
  • Someone has recently backed up a site collection using Stsadm which includes a site collection lock (SP2 supposedly does this automatically)
Issue
  • Attempt to edit the Site Collection Admins from Site Settings results in the following
    • Error:  You need to be a site collection administrator to set this property
  • Attempt to load a page which does any advanced processing
    • Access Denied
Resolution
  • The Site Collection was Locked (Read-only).  Unlock it via Central Admin (_admin/sitequota.aspx)
    • Set to Not locked

Friday, November 6, 2009

Reorder Page Permission Error

Scenario
  • Created a Links list with item level permissions and User Sorting enabled on a View.
  • Current user has Contribute access to the list with only access to some items (ex: only their own)
Issue
  • The following Error occurs when Clicking the Reorder Menu item

    • You don't have enough permission to access this page. at Microsoft.SharePoint.ApplicationPages.ReorderPage.OnLoad(EventArgs e)
      at System.Web.UI.Control.LoadRecursive()
      at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

Resolution
  • You cannot use the out of the box reorder feature when you are using item-level permissions.
    • The user must have edit permissions on every item in the list in order to reorder.
  • Instead, create your own order column and manually configure the sort order in your Views.

Thursday, November 5, 2009

The trial period for this product has expired.

Scenario
  • You installed MOSS 2007 SP2 soon after it was released
Issue
  • You receive the following message

    • Error: The trial period for this product has expired.

Resolution

Loading this assembly would produce a different grant set from other instances

Scenario
  • An assembly (dll) is installed in both the GAC (global assembly cache) and in the App_Bin folder
Issue
  • When browsing to the site you receive the following error:
    • Loading this assembly would produce a different grant set from other instances
Resolution
  • Remove the App_Bin dll