SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have an aggregated display of Publishing Pages based on an expensive query which includes permissions, page location, page content type and publishing state, which means I'm caching the results of the query.

Now I'm looking for a way to invalidate this cache when necessary, which means I need to to know when a Page is published (including immediately after creation) or unpublished (including as a result of deletion), since this will invalidate the cached query result.

I've looked into the available mechanisms for determining when this happens, but what I've found so far doesn't quite seem to cut it:

SPFormContext.OnSaveHandler - this seems specific to the Save button in the ribbon and wouldn't let me trap a Publish from, say, Manage Content and Structure. Right?

SPItemEventReceiver.ItemUpdated - this doesn't seem to receive notifications for Publish and Unpublish. Right?

Is there a way to subscribe to the kind of "OnPublish" and "OnUnpublish" events I'm looking for? Or is there a different solution altogether?

share|improve this question

There are no events specific to publishing pages. They are just ordinary documents (.aspx files) in a document library (the Pages library) that have been enhanced by the publishing API.

So, you're on the right track with SPItemEventReceiver.ItemUpdated. Compare BeforeProperties with AfterProperties, specifically the Level field. A value of 1 means the file is published.

I can't test that right now so if it doesn't work, you can try checking the SPListItem.Level and/or SPListItem.ModerationInformation properties on SPListItemEventProperties.ListItem. The downside here is you won't know the "before state".

share|improve this answer
BeforeProperties and AfterProperties never contain a property named Level. There is a property named ` which looks like it could be used (a boxed int), but it never differs between BeforeProperties and AfterProperties - it just jumps from 255 to 1 or 2 sometimes. – ScarePoint Apr 12 '11 at 9:10

Did you try using SPSiteDataQuery or CrossListQueryInfo instead? This already handles caching and filtering is done using CAML.

Check Waldek's blog post where he monitors performance of different approaches. Another post by Ton Stegeman here

share|improve this answer

I did implement it like this:

Is only working in the ItemUpdating() event handler:

        public override void ItemUpdating(SPItemEventProperties properties)

            if (properties.ListItem == null)

            SPListItem item = properties.ListItem;
            string iBefore = Convert.ToString(properties.BeforeProperties["vti_level"]);
            string iAfter = Convert.ToString(properties.AfterProperties["vti_level"]);

            if (item.Level == SPFileLevel.Published && iBefore.Equals("1") && iAfter.Equals("1"))
                //DO the action here
        catch (Exception ex)
            //Log it

The event is triggered when a page is unpublished or a document (in a doclib with major and minor versioning on) is changed from a published version to a draft (ECB - Unpublish this version)

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.