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?


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

| 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

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

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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