When we need to validate something or put restriction before adding or modifying data, at that time we need to use ItemAdding or ItemUpdating Event Handler, here I’ll demonstrate how to access fields of List into event handlers.
Example:
As per my requirements, I don’t want to add duplicate Name into List. For this I need to check that condition before I add and update item to List, I need to use “ItemAdding” and “ItemUpdating” event handlers
public override void ItemAdding(SPItemEventProperties properties)
{
string strName = string.Empty;
foreach (DictionaryEntry entry in properties.AfterProperties)
{
if (entry.Key.Equals("Name"))
{
strName = entry.Value.ToString();
}
}
SPList list = properties.OpenWeb().Lists[properties.ListId];
SPQuery query = new SPQuery();
query.Query = "<Where><Eq><FieldRef Name='" + list.Fields["Name"].InternalName + "' /><Value Type='Text'>" + strName + "</Value></Eq></Where>";
if (list.GetItems(query).Count > 0)
{
properties.Cancel = true;
properties.ErrorMessage ="Name already exists!";
}
}
public override void ItemUpdating(SPItemEventProperties properties)
{
string strName = string.Empty;
foreach (DictionaryEntry entry in properties.AfterProperties)
{
if (entry.Key.Equals("Name"))
{
strName = entry.Value.ToString();
}
}
SPList list = properties.OpenWeb().Lists[properties.ListId];
SPQuery query = new SPQuery();
query.Query= "<Where><And><Neq><FieldRef Name='"+ list.Fields["ID"].InternalName+ "' /><Value Type='Number'>"+ properties.ListItemId+ "</Value></Neq><Eq><FieldRef Name='"+ list.Fields["Name"].InternalName+ "' /><Value Type='Text'>"+ strName+ "</Value></Eq></And></Where>" ;
if (list.GetItems(query).Count > 0)
{
properties.Cancel=true;
properties.ErrorMessage ="Name already exists!";
}
}
Monday, June 22, 2009
How to access fields of List Item in ItemAdding and ItemUpdating event handlers into SharePoint
Labels:
Event handler types,
eventhandler,
How to access fields of List Item in ItemAdding and ItemUpdating event handlers into SharePoint,
ItemAdding and ItemUpdating,
ItemAdding and ItemUpdating in eventhandler,
ItemAdding in Eventhandler,
ItemUpdating in Eventhandler,
MOSS 2007,
Sharepoint,
Sharepoint Event Handler Example,
SharePoint event handlers,
Sharepoint Event Hanlder,
Sharepoint Event Hanlder Types,
sharepoint eventhandler,
SPItemEventProperties,
Synchronous Event Handler in sharepoint,
Synchronous Event Hanlders in Sharepoint With ItemAdding and ItemUpdating,
Synchronous EventHandler in sharepoint
Subscribe to:
Post Comments (Atom)
Hi,
ReplyDeleteGreat post. I have tried it but don't seem to get it working. I implemented the ItemAdding event handler but instead of sharepoint displaying the error nicely I get a server error page, although the error message I wanted to display appears. Is there another place I should modify? Or am I missing something? Any help would be nice.
Thank you.
Hi,
ReplyDeleteSolved the problem. It had something to do with my web.config . The changes I made:
...
...
...
Thanks.
Alexandra
ReplyDeleteThanks for comment and also giving feedback. What changes you did to web.config to solve your problem? I think you made changes for CallStack and CustomErrors. If possible please share details.
Thanks and Regards
Hi Disha,
ReplyDeleteThis is exactly what I'm looking for! However, I have a quick question. In your foreach loop, why did you use the type DictionaryEntry? Where did this value come from, and how should I change it?
Thanks for the post
Hi
ReplyDeleteThanks for appreciation and comments. Now when you save a particular ListItem, all field values that we entered of that listitem store as type DictionaryEntry (System.Collections).
I think, you can also try below lines of code and may be it solves your problem.
public override void ItemAdding(SPItemEventProperties properties)
{
string Name = "";
using (SPWeb web = properties.OpenWeb())
{
Name = web.Lists[properties.ListId].Fields["Name"].InternalName;
}
properties.AfterProperties[Name] = "ChangedValue";
}
Enjoy !!!!!!!
Hi Disha,
ReplyDeleteI wrote similar code to validate the data while user is entering in the columns of a list but writing code in event handlers with properties.errormessage= some text will display a new page with go back to the site option where user has to go back and reenter the data from scratch, instead we can use jscript so that the error message will be shown in a pop-up window and data in other columns remains unaltered and after pressing ok they can edit the column with correct data.I am thinking so but I have no idea how to do that.Can you give me some idea?
Hi Disha,
ReplyDeleteI am sorry to include this comment here but I want your suggestion. I have 2 lists namely 'Tasks' list and 'stages' list.Tasks list will have an 'TID'(task id)'Create a Stage?' and 'link to the Stage list' columns along with some other columns, so when creating a item(new task) in tasks list if they say 'yes' for 'Create a stage?' column they will see a link to that corresponding stage list in the 'link to stage list' column and this data will get copied in to that Stages list automatically all this i did using event handlers.So the stages list will consist of all the stages for all the tasks in the tasks list with unique task ID's and Stage ID's.Now where I got struck is I have to show them only stages of a that particular task in the Stages list if already existing or I have to copy this data and make them create new stage when they click on 'link to stage list' in tasks list, it means filtering has to be done automatically in the stages list with respect to the TID value in the Tasks list.Except filtering part I wrote all other code for item added/updated and deleted cases.Do you have any idea or webpart apart from writing custom filter code?
Any suggestion is appreciated.
Harish,
ReplyDeleteI like your requirement and it’s very interesting. Good work!
Now if you are looking for any Filter web part, then I think you can use and play with out of the box Filters web part, "SharePoint List Filter” web part is one of the out of the box web part, in this web part you need to select List Name, select filter column names and then you can send output or results to any another web part into page …
So please see whether you can leverage and use "SharePoint List Filter” web part or any other out of the box Filters web part or not. I think custom coded filter web part is last option if you didn’t find anything from out of the box.
Good Luck!!
Disha Shah :)
Harish,
ReplyDeleteLogically there must be some way in which we can write JavaScript into event handler functions, but I think properties.ErrorMessage behavior is out of the box, though I have found below links, may be you can find something helpful for you.
1 . Very good link :
http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/22d79c27-e5ef-4b29-b845-b54976940f3a/
2. Link talks about that you can’t use JavaScript into event handlers.
http://phani-madhav.blogspot.com/2008/03/custom-script-while-submiting-list-item.html
3. http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/945591e2-da92-4b60-881f-b9da89999634
4. http://www.sharepointkings.com/2008/06/redirection-from-event-handler.html : check about SPUtility.redirect method and may be you can redirect control to same page instead of writing properties.ErrorMessage values.
Enjoy,
Disha Shah :)
Thanks for your suggestion Disha. I will look in to Sharepoint list filter webpart and let you know what solution I choose finally.
ReplyDeleteHi Disha,
ReplyDeleteI have tried using list filter webpart and query string url filter webpart but I didnt get the solution may be I didnot make a wright approach using these filters but I just modified my list view filter like filter when column ID is equal to[ID] and in my event handlers in the column where I hardcoded the link to another list I did smthng like after http://....TIDView.aspx? + "?ID=" + newitem["ID"]); . In fact this is the basic idea of a query string filter.
Thus I got the soulution.
Hi,
ReplyDeleteThis is Harish again.I got an issue with event handlers I have a list in a publishing site on which I wrote 2 event receivers and each of which furthur includes 3 types of event handlers(item added/deleting/updating same in both the cases). Here the problem is in item updating case I am getting Save conflict error I thing every developer using updating event handlers might have seen this . I am even using disable and enable event firings but still unable to get rid of that error. I am using updating event because while item updating for a column 'Status' I need to check what its value is before.properties and after.properties(open/cloesd). Can you help me?
Hey Harish
ReplyDeleteThat's really good that you got your solution by filter web part. Great Job!!
Disha Shah :)
Hi Harish,
ReplyDeleteYeah I also got same type of problem while working with event handlers, below are the steps which I followed to resolve my issue, you can also try to do same thing and see whether it�s will solve your problem or not.
For every update to a list item the SPList.update() method needs to be called to save the changes back to database. The pattern which I like to follow is to retrieve the SPWeb GUID from the current site, then call a separate instance of SPWeb object per individual list update. I know that this is a tedious pattern and doesn't necessarily have to be used on all occasions, but may be it will save you from this annoying little exception.
Sample Code:
protected void itemUpdate(string FieldName, string FieldValue, SPSite site, Guid webID, Guid listID, Guid itemID)
{
try
{
using (SPWeb web = site.OpenWeb(webID))
{
web.AllowUnsafeUpdates = true;
SPList list = web.Lists[listID];
SPListItem item = list.Items[itemID];
item[FieldName] = FieldValue;
item.Update();
list.Update();
web.AllowUnsafeUpdates = false;
}
}
catch(Exception ex)
{
Response.Write("An error occured while updating the items");
}
}
When disposing of SPWeb object, remember CONTEXT things also. If you retrieve SPWeb object from the current context (SPContext.Current.Web), you cannot and should not dispose of SPWeb object.
If you dispose of the Web which is being used by the current context, it's the equivalent of ripping the ground from under your feet!!
If you are doing multiple list updates the best approach would be to open and dispose of a separate instance of SPWeb object.
Disha Shah :)
Thanks for the Code Disha,
ReplyDeleteI have already tried this code but this didnot work but finally I solved the problem by replacing properties.listitem.update() with properties.listitem.SystemUpdate(false)in item updating event handler.
Regards,
Harish
Hi Harish,
ReplyDeleteIt’s good to know that you got the solution.
Thanks for sharing the information.
-Disha Shah
Hi Disha
ReplyDeleteI need to create alert through sharepoint object modal for logged in users. If logged in user subscibe alert in my custom webpart for any docuemnt libraray item, than when ever that subscribed item will modify, user will get alert with that document url. i have a webpart which shows the selected documents from document library. Over there i need to give this fcility.
Thanks in advance.
Regards
Sai
Hi Sai
ReplyDeleteI think you can fulfill your requirement by Alerts Facility from SharePoint Interface only, there is no need to go for SharePoint Object Model.
Please let me know why you want to use SharePoint object model?
Best Regards
Disha Shah
Thanks for sharing ur knowledge to others..
ReplyDeleteHi,
ReplyDeleteGreat work. I am trying to used it in my sharepoint site but the entry.Key doesn't seem to show the internal name. I have a content type that I have created programatically with columns that I gave internal names, but they don't seem to show in entry.Key. Can you please help me?
Thanks.
Have a great day,
Anisia
Hi Anisia
ReplyDeleteEntry.key may return the display name of the field. So you can get internal name by using this code
SPList list = properties.OpenWeb().Lists[properties.ListId];
foreach (DictionaryEntry entry in properties.AfterProperties)
{
Strint strIntername = list.Fields[entry.Key].Intername;
}
Hope this helps!!!Please let me know and describe in detail if I am unable to understand your problem correctly.
Thanks & Regards
Disha Shah
Thanx but i want to access item field insade property such as Due Time and Assigned to
ReplyDeletehow can i do that ??
Hi Tarhoni,
ReplyDelete"Due Time" and "Assigned To" these two are Fields for the current List Item? If yes, then you can add like these
string strDueDate = string.Empty;
string strAssignedto = string.Empty;
foreach (DictionaryEntry entry in properties.AfterProperties)
{
if (entry.Key.Equals(“DueDate”)) \\internal name of duedate
{
strDueDate = entry.Value.ToString();
}
else if (entry.Key.Equals(“AssignedTo”)) \\internal name of AssignedTo
{
strAssignedto = entry.Value.ToString();
}
}
Hope this helps!!!
Thanks & Regards
Disha Shah
Hi Disha,
ReplyDeleteNice blog.
Disha, i m getting problem in ItemAdded event where i m not able to display error message.
Properties.Errormessage = "error";
properties.cancel = true;
Thanks & Rgds,
Hardik Shah
Hi Hardik
ReplyDeleteThanks for the appreciation!!!
One question raised in my mind for your question,
If it does not display that error message it means there is some problem before that line.If possible, Can you please post that code before that line so it makes easier for me to solve your problem?
Thanks & Regards
Disha Shah
Hi Disha,
ReplyDeleteThanks you so much.
since Last 2 days i have been trying to get item value in the variable in itemadding event. but each time it gives error null ref.
But using dictionaryEntry i can able to get the values.... :)
Regarding my earlier post:
ItemAdded problem:
I have written spquery and its give me the record. till that everything is good.
now;
SPListItemColletion TimeList = CRBlist.GetItems (TimeQuery);
if(TimeList.Count > 1)
{
Properties.ErrorMessage = "Error massage";
Properties.Status = SPEventReceiverStatus.CancelWithError;
Properties.Cancel = true;
}
}
}
This code in not in any try or catch block. This code is in ItemAdded event.
Hardik
ReplyDeleteJust change the order of the statement that you have written for eventhandler.
//Properties.Status = SPEventReceiverStatus.CancelWithError; --Do not write this one and try
properties.Cancel = true;
properties.ErrorMessage = "Deleting is not supported.";
Hope this helps!!!
Disha Shah
Hi Disha,
ReplyDeleteI have question regarding 'ItemAdding' event handler, I have attached my 'ItemAdding' event to my document library and I need to take some meta data associated with uploading document and compare with values, but I am not getting List Item ID and not getting any key/values by accessing after properties object.
Do you know any way to get Meta data associated with documents in 'ItemAdding' event handler?
Thanks for looking into above question :)
~Sanket
Hi Disha,
ReplyDeleteI want to encrypt the document before it is added to SharePoint DB. This should handle all the events which can result into document being added into SharePoint such as Add, Check In etc. So can you please help me to achieve above.I have tried the ItemAdding, ItemCheckIngIn events but its giving “Your changes conflict with those made concurrently by another user. If you want your changes to be applied, click Back in your Web browser, refresh the page, and resubmit your changes” error.
Also is there any way I can get the events for View/Edit document link so on that I can decrypt the document.
Regards,
Dharmesh
Hi Dharmesh
ReplyDeleteThis error occurs case when you save that item same time some other event is also trying to update that item.
Is there any workflow attached to document library? You can use either "check-in" or add document event handler not use both at the same time on document library.
If workflow attached use this one to avoid the error.
web.AllowUnsafeUpdates = true;
ListItem.SystemUpdate(false);
or
ListItem.Update();
web.AllowUnsafeUpdates = false
If any question please let me know.
Are you using Sharepoint 2007 or Sharepoint 2010?
Disha Shah
Hi Disha,
ReplyDeleteI love your work. I have the same requirements as above and using Sharepoint 2007. Where exactly do you put this sample code?
Hi
DeleteThanks for appreciating my work!!!
I have used this code inside Eventhandler in VS 2008.
If you need more information, let me know.
Thanks
Disha Shah
Was in grave despair and on the verge of acute trichotillomania... then I muttered another desperate prayer, and was halfheartedly looking at google results when I stumbled on this. it looked a bit different then I gave it a try, I nearly jumped out of my chair when I saw the ever elusive afterproperties in ItemUpdating show their presence in my test loop.
ReplyDeleteDisha - I'm loyal