Wednesday, February 06, 2008

Sample event handler to set a field as a pr imary key (enforce no duplicates)

Got this as a request from a reader- how to prevent users from adding items with same titles as ones that already exist in the list.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;

namespace SPSTIPS.SharePoint.EventHandlers
{
    public class TitlePrimaryEventHandler:SPItemEventReceiver
    {
        const string TITLE_QUERY = @"<Query><Where><Eq><FieldRef Name=""Title"" /><Value Type=""Text"">{0}</Value></Eq></Where></Query>";
        public override void ItemAdding(SPItemEventProperties properties)
        {
            if (properties.AfterProperties["Title"] != null)
            {
                //get the title of the new item
                string currentTitle = properties.AfterProperties["Title"].ToString();
                //get the web site object
                using (SPWeb web = properties.OpenWeb())
                {
                    //get the current list
                    SPList list = web.Lists[properties.ListId];
                    //query the list to check if there are items with the same title
                    SPQuery q = new SPQuery();
                    q.Query = string.Format(TITLE_QUERY, currentTitle);
                    SPListItemCollection itemsWithSameTitle = list.GetItems(q);
                    //if there are items, cancel the add, and show an error to the user.
                    if (itemsWithSameTitle.Count > 0)
                    {
                        properties.Cancel = true;
                        properties.ErrorMessage = "There is already an item with the title \"" + currentTitle + "\ in this list".";
                    }
                }
            }
        }
    }
}

2 comments:

Casey said...

I had already written exactly this for my current client .. but you should also be aware that the event needs to be on ItemUpdating as well as ItemAdding, or you can edit an item to create a duplciate key.

Anonymous said...

should you really have the string "query" and "/query" on the literal??