Tuesday, December 8, 2009

Bug: Security Trimming using Update Personal Web Parts permission

  • You have disallowed Update Personal Web Parts on a site
  • You have enabled Update Personal Web Parts on a page within the site
  • The page uses SPSecurityTrimmedControl with PermissionsString="UpdatePersonalWebParts"
  • The item does not appear on the page even though they have permissions on the page
  • This is a MS bug due to the SecurityTrimmedControl referring to the Site level permission instead of the Page level permission
  • You will need to use another trimming mechanism until MS fixes this bug.

My Links SharePoint list web part mods using HtmlFilter

  • Modify the standard Links List web part properties using HtmlFilter as follows

    • Remove column header
    • Clear empty group by selector
    • Offer open link in new window option

  • Add an OpenInNewWindow yes/no column to the Links List
  • Add a Group column to the Links List

    • This can be any type that supports Grouping

  • Add an OpenInNewWindowReplace calculated column to the Links list

    • Calculation:   =OpenInNewWindow&"OpenInNewWindowReplace"

  • Create a view 

    • Group on the Group column
    • Groups should be Expanded
    • Include the OpenInNewWindowReplace calculated column

  • Add the default Links List web part to a page on the site

    • Set the web part view to the newly created view from the previous step
    • Append the following to the Web Part description (under advanced)

      • RemoveColumnHeadersAndBlankGroup

  • Add the following HtmlFilters to the page, masterpage, or to a SmartPart on the page (VB.Net syntax).  For C#, change the "" to \"  and ' to // and don't forget your ;'s
'Remove Blank Grouping from Web Parts with "RemoveColumnHeadersAndBlankGroup" at the end of the Web Part description. Updated to ignore expanded group, due to ajax population resulting in hiding the entire section.
FilterReplaceValues.Add("(?is:(?<first>RemoveColumnHeadersAndBlankGroup""(.(?!class=""ms-gb""))*?titl(?<title>\d+)-1_"")(?<second>(.(?!MSOZoneCell_WebPart))*?Group</a> :&nbsp; <span(.(?!TBODY id=""foot))+?isLoaded=""true""))", "${first} style=""display:none"" ${second}")
'Remove Column Headers from Web Parts with "RemoveColumnHeadersAndBlankGroup" at the end of the Web Part description
FilterReplaceValues.Add("(?is:RemoveColumnHeadersAndBlankGroup(?<first>"".*?<TR class=""ms-viewheadertr""))", "${first} style=""display:none""")

'Links with preceding "TRUEOpenInNewWindowReplace" calculated column values should open in a new window
'Hide the OpenInNewWindowReplace Calculated Column Header
FilterReplaceValues.Add("(?is:<TH (?<first>(.(?!</TH>))*?OpenInNewWindowReplace.*?</TH>))", "<TH style=""display:none"" ${first}")
'TRUE (yes)
FilterReplaceValues.Add("(?is:<TD (?<first>(.(?!</TD>))*?"">TRUEOpenInNewWindowReplace</TD>.*?<A .*?) HREF)", "<TD style=""display:none"" ${first} target=""_blank"" HREF")
'FALSE (no) or nothing (blank)
FilterReplaceValues.Add("(?is:<TD (?<first>(.(?!</TD>))*?"">(FALSE)?OpenInNewWindowReplace</TD>))", "<TD style=""display:none"" ${first}")

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.

  • 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

  • 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)
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

  • 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
  • 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 ???

  • 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

  • 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)
  • 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
  • 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

  • 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)
  • 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)

  • 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.

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

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


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

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

Thursday, October 22, 2009

Back from SharePoint Conference 2009!

Lots of new stuff coming in 2010.  Looks like the best bet is to use the keyword  #SPC09 for all the new stuff.

Good news is that HtmlFilter will be just as useful, if not more-so.

Thursday, October 15, 2009

Thursday, October 8, 2009

Web.Config Custom Configuration sections with RSA

After spending awhile playing with RSA and Custom Configuration Sections I added the following community content:
  • You must compile your ConfigurationSection class as a strongly named assembly (dll) and deploy it to the GAC
    • If you don't, it will try to locate your class in System.Web
  • You should add this to the Compilation\Assemblies section of the Web.config if you will be using the values within a Web Site project (non pre-compiled)
    • Ex: <add assembly="Samples.AspNet, Version=, Culture=neutral, PublicKeyToken=DllPktHere" />
  • The following section declaration should include the full strong named assembly
    • Ex: <section
      type="Samples.AspNet.PageAppearanceSection, Samples.AspNet, Version=, Culture=neutral, PublicKeyToken=DllPktHere"
  • Follow the RSA encryption instructions (http://msdn.microsoft.com/en-us/library/ms998283.aspx)
    except for the following:
    • You may need to use the -pef format instead of -pe
    • If you have your section within a group as in the example above, you should use this format: "SectionGroupName/SectionName"
      • This would be instead of the "connectionStrings" section used in the RSA encryption instructions examples.

Thursday, September 24, 2009

Blank UpdatePanel in UserControl

  • Editing a UserControl in VS 2008 with html <style> tags in the UserControl
  • The Designer window is empty as if the updatepanel is invisible (visible=false)
  • Place the Style tags at the bottom of the usercontrol, below any UpdatePanels
    • This is a known bug

Monday, September 21, 2009

Personalization and Audience Targeting Reset Page Content Bug

  • Personalization and Web Part Audience Targeting are both enabled on a MOSS 2007 page.
  • Some web parts are audience trimmed for a particular user
  • That user personalizes the page
  • The user selects "Reset Page Content" from the User Welcome Menu
    • Or they select "Reset Web Part Content" from the Web Part's "Edit" menu
  • The audience trimmed web parts are incorrectly shown to the user
    • This may be a security issue if the audience targeted web part has confidential information on it
  • After refreshing the page, the page displays correctly
  • I developed the following simple workaround
  • Add the following usercontrol (2 files) to the 12 Hive\Template\ControlTemplates folder
    • PersonalizationResetPageContentRefreshBugFix.ascx
    • <%@ Control Language="VB" AutoEventWireup="false" CodeFile="PersonalizationResetPageContentRefreshBugFix.ascx.vb" Inherits="UserControls_PersonalizationResetPageContentRefreshBugFix" %>
    • PersonalizationResetPageContentRefreshBugFix.ascx.vb
    • Partial Class UserControls_PersonalizationResetPageContentRefreshBugFix
          Inherits System.Web.UI.UserControl
          Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
              Dim strPageRestore As String = Request.Form.Get("MSOWebPartPage_RestorePageDefault")
              Dim strPartRestore As String = Request.Form.Get("MSO_RestoreSettings")
              If Not String.IsNullOrEmpty(strPageRestore) OrElse _
                      Not String.IsNullOrEmpty(strPartRestore) Then
                  'Force a client side redirect and end response so no untargeted info goes to client.
                  Response.Redirect(Page.Request.Url.AbsoluteUri, True)
                  'Response Ends
              End If
          End Sub
      End Class
  • Add the following lines to each master page where personalization and audiences are used
    • The following line goes with the other Register tags at the top of the master page
      <%@ Register TagPrefix="wssuc" TagName="PersonalizationResetBugFix" src="~/_controltemplates/PersonalizationResetPageContentRefreshBugFix.ascx" %>
    • The following line goes within the BODY/FORM section
    • <wssuc:PersonalizationResetBugFix id="IdPersonalizationResetBugFix" runat="server" EnableViewState="false"/>

Monday, September 14, 2009

Error enabling Publishing Feature - WebAdminPageBase.OnLoad File Not Found

  • Enabling the Publishing Feature on a new Team Site
  • Accessing the site via a url not mapped in the Alternate Access Mappings list
  • Encountered the WebAdminPageBase.OnLoad "File Not Found" error
  • Add the Alternate Access Mapping for the url you are trying to use

MS SharePoint "so-called" Support

Some of my open/past SharePoint support issues.  Note that I always post my MS Support Tickets to the MS newsgroups with an issue to foster community participation and help others.

Open (Or given up on) Issues
  • None at this time.
Issues Resolved by Me
Issues Resolved by Community
Issues Resolved by MS
  • You think there'd be one. :-(

Domain Username not resolving - People Picker

  • You attempt to specify a domain user in any People Picker field within SharePoint 2007 / 3.0
  • AD domain users have resolved before.
  • The application service is running under a local machine account
  • The username will not resolve.  Instead you get the squiggly red underline.
  • Workaround: Change the Service Account to a domain user account

I do not know why a local account would exhibit this behaviour nor why this would randomly stop working.  After changing to a domain account temporarily you can change back to a local account, but the issue will occur again.  My guess is that it's environment specific, such as a temporary loss of AD connectivity, which would explain the intermittant occurances.

Tuesday, September 8, 2009


Issues with SPUtility.SendEmail.
  • SPUtility.SendEmail subject parameter cannot contain a comma "," character.
    • If it does, the email will be delayed by several hours.
    • To workaround, use: strSubject.Replace(",", " ") for the subject parameter
    • I am not sure if this is an smtp issue or a SPUtility issue.
    • The function will return "True" indicating a successful send even if there is a comma.
  • The body text parameter must have a new line character at least every 2048 characters.
    • If not, the email body will be truncated at 2048 chars.
    • For example, when using an HTML formatted body, you may have all your encoding on one line within the body string/stringbuilder parameter. You will need to insert crlf chars every 2048 characters or less.

Wednesday, August 26, 2009

SharePoint Synchronous Mirror Script



  • When setting up the SQL script they left out a few details.
  • Use C:\Windows\System32\cliconfg.exe to create the aliases on each SharePoint server. SharePoint must point to the alias rather than directly to the SQL instance.
  • The SQL alert should run the Failover job
  • The Failover job should have the 2 steps
    • Failover the remaining databases
    • Run the Regini commands to reset the sql alias
      • The account running the job must have add permissions or you may get an Regini cannot open file error
      • The sql job can only run one cmdexec command per step, so you will need multiple steps or a batch file with all the commands
      • The registry setting should change the alias pointer to the same server that the job is running on
  • Don't Copy from the word doc, as this will take the incorrect - and ' characters.

Crawl Schedule: Access is denied.

  • Attempting to add a crawl schedule for a newly created SSP

  • Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))


SSP: Could Not Connect To Server


  • .Net 3.5 SP1 was installed prior to MOSS 2007 SP2
  • On the SSP Content Sources screen: "Authentication failed because the remote party has closed the transport stream"
  • Could not connect to server [Index/Query Server Name] for application [SSP name] shows up in the SSP Search Settings/Administration screen

Wednesday, August 19, 2009

LdapRoleProvider and Audience Targeting Bug

The MOSS 2007 LdapRoleProvider could be your greatest friend or your worst enemy. Getting it configured correctly is a pain. See the community content I added here for some of my tricks.

There are some limitations on SharePoint role providers:

  • Cannot use the people picker search feature to find partially typed group names
  • You can only have one provider per SharePoint application zone
  • You cannot share a provider across applications/zones
  • The role provider groups cannot be directly accessed via Audience targeting

Today, I spent the day figuring out the following bug and resolution.


  • You have configured audience targeting to use SharePoint groups because you cannot directly target Ldap groups
  • The SharePoint groups contain the Ldap groups
  • The SharePoint groups have no inherent permissions defined


  • The targeted web part does not display even though the user is in the appropriate ldap group


  • The SharePoint group must have at least one permission applied to it.
  • I recommend using the Read or Restricted Read permission, since this should be a minimal permission. Alternatively, create your own minimal permission level.

My guess is that the SP group only parses the RoleProviders upon a permission request. This means that if there have been no relavent permission requests against the group, the group will only contain the non-roleprovider entries (individual accounts) and will not return the correct results to the audience targeting request.

Monday, August 3, 2009

Network Load Balanced (NLB) Reporting Services Integrated Installation - Unresolved

  • Installing SSRS on 2 content switch load balanced (NLB) MOSS 2007 front end web servers.
  • Using SharePoint Integrated mode.
  • Separate Database server hosts databases for both SSRS and MOSS
  • SSRS is correctly configured and will run when configured directly to either FEW/SSRS server.


  • SSRS will not run via the NLB URL.
  • Error parsing lists shows up in logs.

SiteManager Error


  • Using Site Actions / Manage Content and Structure (this is a Publishing Feature)
  • Recently changed the Application Pool's service account via IIS.

  • You are not authorized to view this page.
  • HTTP error 403 - Forbidden


  • Change the application pool account to the MOSS installation user account
  • Make sure to use the SharePoint Central Admin UI to change service accounts in future

Purpose of this blog.

I am creating this blog to document the struggles and (hopefully) solutions I encounter in my day to day experiences with Microsoft Office SharePoint Server 2007.

I have been working with this product since the Beta and encounter a new issue/error almost every day I've worked with it.