Sunday, June 24, 2012

Sharepoint bug: incorrect itemId in summary alerts with custom alert handler

Some time ago I faced with strange behavior. Custom alert template with custom alert handler was used for alerts for particular list. Immediate alerts worked successfully and custom alert handler was called properly. However summary daily alerts didn’t work.

Custom alert handler is inheritor of IAlertNotifyHandler interface which allows you to override default behavior of alerts processing. E.g. you may log all alerts with custom handler. Here are several examples which shows how to implement custom alert handler step by step: SharePoint – Customizing Alert emails using IAlertNotifyHandler, How To: Customizing alert emails using IAlertNotifyHandler. Shortly you need to override IAlertNotifyHandler.OnNotification method. It has single parameter of SPAlertHandlerParams type. In turn it has SPAlertEventData[] eventData property.

When custom alert handler processes immediate alert (which is caused e.g. by adding new item) eventData has single element and its itemId property contains integer identifier of the list item which caused alert. Using this identifier you may open list item in your handler and read its metadata, e.g. determine user who modified this item.

When summary alert is processed, eventData contains several items – separate item for each event. The problem is that if you will iterate through collection and get eventData[i].itemId you will get any except correct integer identifier (it can be 0, 186, 1932917208, etc., while real identifiers will be 10, 11, 12). For me such behavior looks like a bug.

This issue was mentioned also in this forum thread: SPAlertHandlerParams - not behaving correctly for daily alerts. And author Johnny Dogbert provided workaround:

   1: string url = ahp.eventData[i].itemFullUrl;
   2: int itemId = int.Parse(url.Substring(url.LastIndexOf('/') + 1).Replace("_.000", ""));

It works because in itemFullUrl for list items Sharepoint passes the following URL: testsite/Lists/Test list/10_.000. I.e. we just get id from URL. Note that for documents it won’t most probably work – you will need to open SPFile from url and get its id using SPFile.Item.ID property.

This problem is reproducible on Sharepoint 2007. I didn’t test it on Sharepoint 2010, if you will test it please share the results in comments.

2 comments:

  1. Hello,
    Thanks for this post.

    You can make it works for all contents with the following lines of code:
    SPList list = web.Lists[ahp.a.ListID];
    for (int i = 0; i < ahp.eventData.Count(); i++)
    {
    SPAlertEventData mydata = ahp.eventData[i];
    list.ParentWeb.GetListItem(mydata.itemFullUrl);
    }

    ReplyDelete
  2. Thank you so much Rémi MATAYRON your code worked for me

    ReplyDelete