SharePoint Tip of the day : Proper CAML Query with Lookup Field

Based on the value :

<FieldRef Name=”Country” />
<Value Type=”Lookup”>Belgium</Value>

But whenever possible, try to search based on the lookup ID :

<FieldRef Name=”Country” LookupId=”TRUE” />
<Value Type=”Lookup”>10</Value>

Quick reminder : Check if an element exists in JQuery (and hide some button in SharePoint UI !)

For some reasons, I needed to hide the approval button in my SharePoint user interface so the easiest way was to do


Only issue is that when there is no approval button (no approval workflow activated on some web for example), the "Approve and Publish" (qaApprovePublish) becomes the "Publish" button (qaPublish)

So a quick way is to do this when the document is ready :

if ($('#qaPublish').length  && $('#qaApprovePublish').length)
    // both are found, hide the approve button

c# inline code reminder

Just a short reminder for inline code. While I do agree that it should be avoided as much as possible, it comes pretty handy for databindable controls or to quickly test something without recompiling everything.

So here are some quick notes :

Some code that must be executed

    void Page_Load( object sender, EventArgs e )   {  }

<% int id = int.Parse(Request["productID"]); %>

<%= writes out the code inside which means that

<%=productID %>

is equivalent to :

<% Response.Write(productID); %>

Please beware that there is no ";" at the end of your <%= … %> statement in that case.

Databinding management

<%# Eval("productID") %>

your datasource must obviously have the element selected with the right name.

Within a Repeater control, in order to create a customized link :

<asp:Hyperlink runat="server" ID="linkProduct"  NavigateUrl="product.aspx?id=<%# Eval("productID") %>" />

This is always handy to avoid dynamic user control, most of the time, a repeater with the right controls inside will do the job (and its easier to manager)

SharePoint – Quickly Create a custom Edit button

I had several issues with switching a page to edit mode from code (checking out the item, redirecting to the page with the right query string and the right form mode) for some reason, my publishing console was always behaving strangely (not possible to do a check-in, just publish for example).

After several hour of struggling, I found that way, without code behind, that works quite well although that’s really, really ugly. Let’s see if I can find something better but now, I can go home !

[a href=”javascript:if(document.forms[‘aspnetForm’][‘MSOLayout_InDesignMode’] != null) document.forms[‘aspnetForm’][‘MSOLayout_InDesignMode’].value = 1; if(document.forms[‘aspnetForm’][‘MSOAuthoringConsole_FormContext’] != null) document.forms[‘aspnetForm’][‘MSOAuthoringConsole_FormContext’].value =1; if (document.forms[‘aspnetForm’][‘MSOSPWebPartManager_DisplayModeName’]!= null)document.forms[‘aspnetForm’][‘MSOSPWebPartManager_DisplayModeName’].value =’Design’;__doPostBack(‘ctl00$PlaceHolderTopNavBar$ SiteActionsMenuMain$ctl00$wsaEditPage_CmsActionControl’,’switchToAuthoring’)”]Edit the page[/a]

SharePoint annoyance 03 – Irrelevant error when you try to cancel the checking out on your ItemCheckingOut event receiver

When attempting to cancel an item checkout in the ItemCheckingOut event handler the error “Attempted to read or write protected memory. This is often an indication that other memory is corrupt.” is shown to the user. This is a known issue with WSS 3.0 however, there is a workaround. You should set the Status property to SPEventReceiverStatus.CancelNoError instead of SPEventReceiverStatus.CancelWithError or setting properties.Cancel = true;

public override void ItemCheckingOut(SPItemEventProperites properties)
     // your code to check whether or not the current user can do a checkout on the item
     properties.Status = SPEventReceiverStatus.CancelNoError;

However, doing so will not display an error message and in case of a publishing page, SharePoint will think that the page is checked-out and display (un)relevant error when the user will try to checked-in or publish the page. (“page must be first checked-out”)

My solution was instead, to transfer to an error page using the SPUtility.TransferToErrorPage(“You’re not allowed to check-out this kind of file”); to avoid any unexpected behaviour and ensure that the flow is stopped but that didn’t work. Like an asynchroneous operation no error was returned and the usual (wrong) behavior was still there.

So I created a custom error page (in the _layouts folder) that will display any message received as a querystring parameter to fully replace the      properties.Status = SPEventReceiverStatus.CancelNoError;

public override void ItemCheckingOut(SPItemEventProperites properties)
     // your code to check whether or not the current user can do a checkout on the item
   if (currentUserIsNotAllowedToDoCheckOut)
        string errorPage = “/_layouts/BlueOcean/ErrorPages/GenericError.aspx”;
        string errorMessageQueryString = “message=” + HttpUtility.UrlEncode(errorMessage);
        SPUtility.Redirect(errorPage, SPRedirectFlags.Default, currentContext, errorMessageQueryString);

In order to have the context in the event don’t forget to do this


SharePoint annoyance 02 – Don’t forget to specify the right permissions settings on your master page gallery when you define a custom site definiton with a custom master page and you use only custom (non ootb) SharePoint groups

When you have custom groups in your SharePoint solution, make sure that the master page gallery is either inheriting permissions from its parent to include the custom groups that you created (or manually add the required ones).

It took me nearly a day to figure out why I get this kind of error when I was creating a custom (sub) site using a custom site definition with a contributor coming from my custom groups.

The specified ChromeMasterUrl '/_catalogs/masterpage/BlueOcean.master' must be a server-relative url within site collection '/'.   at Microsoft.SharePoint.Publishing.Internal.AreaProvisioner.SetLayoutRelatedProperties(PublishingWeb area, Boolean& updateRequired)

Basically, my custom contributor groups had no read access on the .master file which raised the exception stated above. Fixing the security on the master page gallery solved it.