Pages

Wednesday, September 15, 2010

Sharepoint List Event Handler Types and Example

Hello Friends,
  • Business Case:
    In client organizations there are more than one intranet applications where are related like master- child. So when parent item is deleted at that time all its related child items must be deleted. If not then they are like orphan entries. No use of those entries they just eat up performance when query on that list is executed and also it takes space.
  • Solution:So now delete child entries when its parent entries are deleted we have to use EventHandler in SharePoint.
That’s solution.

Let us go for EventHandler in share point

There are always two types of events attached for every type of event.

1>     Asynchronous – After event occurred
2>     Synchronus –     Before event that occurs

Differences between Sync & Async event handlers are:

1) Synch Event Handler occurs before the event is completed while Asynch occurs after the event is completed.
2) Synch Event Handler is mostly used to stop the event from completion in order to validate few things. It means you can cancel the event using Synch Event Handler while it is not possible to cancel the event from Asynch Event Handler.
3) Synch Event Handler methods has their method names ending with -ing while Asynch Event Handler method names will end with -ed. e.g. ItemAdding, ItemUpdating are Synch Event Handler while ItemAdded, ItemUpdated are Asynch Event Handler methods.
4) Synch Event Handler can be used to Add/Modify the values of list fields while using Asynch Event Handler its not possible as it fires after the completion of event.

Let us look at List Event Handler Solution.
Let me  give you example, I have lists like Program, SubProgram.

So when end user is going to delete Program ,all related its subprogram must be deleted.
Like Parent à Child Relationship. Once parent is deleted we have to delete all its children.
So I created one ListEventhandler.

For any listeventhandler first we have to Implements a related Interface depends on requirement .I have to write Eventhandler for ListItem so I implemented  SPItemEventReceiver.

I added Method is ItemDeleting(Synchronous Event) So after parent list item is deleted this list event handler calls and checkreferencefuntion check whether child list has items with ParentID which we are needed  to be deleted.

I write function because I have more than one child tables for same parent.

So rather than write deleting code for finding child data with same id and deleting data I write code and pass  List and ParentId to that function.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
namespace DeleteData
{
    public class DeleteRefrence : SPItemEventReceiver
    {
        public override void ItemDeleting(SPItemEventProperties properties)
        {
            CheckReferencedata("SubProgram", properties.ListItem["ProgramID"]);
            CheckReferencedata("Department", properties.ListItem["ProgramID"]);
             properties.ErrorMessage = "Parent and Child Items are deleted";
        }
        void CheckReferencedata(String Listname, Object Value)
        {
            SPSite site = new SPSite("SiteURL");
            SPWeb web = site.AllWebs["WebnameWhenthelistsarethere"];
            web.AllowUnsafeUpdates = true;
            SPList list = web.Lists[Listname];
            SPQuery Query = new SPQuery();
            Query.Query = "<Where><Eq><FieldRef Name='ProgramId'/><Value Type='Text'>" + Value + "</Value></Eq></Where>";
            SPListItemCollection AnswerItems = list.GetItems(Query);
            int Count = AnswerItems.Count;
            if (Count > 0)
            {
                for (int index = 0; index < Count; index++)
                {
                    SPListItem item = AnswerItems[index];
                    AnswerItems.Delete(index);
                }
            }
            list.Update();
       }
    }
}

Now we have to register that Eventhandler with that list so when user is delete item we can delete Childitems which are related with that ParentID.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
namespace RegisterEventHandler
{
    public class Program
    {
        static void Main(string[] args)
        {
            Console.ReadKey();
            SPSite collection = new SPSite(http://sitename/);
            SPUser user = new SPUser();
            SPWeb site = collection.RootWeb;
            SPList list = site.Lists["Program"];
            string asmName = "DeleteData, Version=1.0.0.0, Culture=neutral, PublicKeyToken=21ce19119994750e";
            string className = " DeleteData.DeleteRefrence";
            // Register the events with the list
            list.EventReceivers.Add(SPEventReceiverType. ItemDeleting, asmName, className);
          // Clean up the code
            site.Dispose();
            collection.Dispose();
            Console.WriteLine("Sucessfully Registered");
            // Return to calling environment : Success
            Environment.Exit(0);
        }
    }
}

Disha Shah

51 comments:

  1. hey buddy ...
    excellent article...and very helpful too can u plz tell me wht if i need to place an event handler on say delete button in People and Group section ....
    Thanks alot in advance...

    ReplyDelete
  2. Sahil,

    Thank you very much for your comment.

    Now regarding your question, can you please explain your question in detail?

    If I understand correct, then you are looking for adding event handler into link called “Remove Users from group” into People and group sections, please correct me if I am wrong.

    As per my understanding there are two alternative ways to achieve same functionality, “People and group” is noting but custom list, so try to find LIST ID of People and group sections and put same LIST ID into event XML file.

    Second way would be, add new custom link into “Actions” menu toolbar into “People and group” and call one custom ASPX page on click on new custom link, after custom ASPX page, you can write event handler in same ASP.NET manner. You can add custom link into any toolbar with “custom actions” with SharePoint

    Enjoy Coding
    Disha

    ReplyDelete
  3. Hi,

    I create a workflow (Sharepoint default Approval workflow) in the document library of site collection A, when the document is as of approved i need to trigger my event handler to add this particular document to the Site Collection B.

    My problem is workflow works fine but if the document is approved the workflow status will also be changed to Approved, but my event handler doesnto triggers.

    Actually i write my code in the ItemUpdated() method. when the workflow status is changed it does not trigger. Also i check the same in ItemUpdating() method too.

    Kindly suggest me plzz


    Thanx in advance,

    here is my thread

    http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/e2b61937-b941-41aa-8bd9-2a1c1e56672c

    ReplyDelete
  4. Hey,

    I think you need to write your event handler code into SharePoint “tasks” list instead of your “document library”, because the workflow status column is not tightly attached to your document library, workflow column is one of the workflow content type which is associated with list, in which we can see status of current workflow steps, from my understanding event handler fires on list when any column values changes. In your case, it’s changing workflow history list/column when your document approved.

    Try to trigger your code into tasks list.

    One more alternatives as per your requirements: if you will write/create your workflow from visual studio then you can write your logic for moving documents from one site collection to another into “task completed” or “task changed” activities …even if, out of the box workflow fits fine for your requirements.

    I hope above information will help you.

    Thanks,
    Disha Shah

    ReplyDelete
  5. Hi Disha,

    Thanx for the reply. Your solution is good and fine. But now i solve it in an different way,

    i create an Three-Stage Workflow for the Source Document Library and for that i create a metadata column as WF Status as type Choice, i add three items in the choice as New, Reviewed, Approved. in the evnt handler i check the WF Status column. if the Status column is Approved then the event handler triggers the approved document to the destination site's destination Document library.

    Its working fine

    ReplyDelete
  6. Hi Disha,

    Many thanks for the detailed and easy to understand article. I am not greatly experienced with SharePoint API and only just begining to get my self familiar with it.

    On this post, I have a question.

    If I created an EventHandler let's say 'ItemAdded' on a list (eg Tasks List) on a Sharepoint Site. Now I save this whole site as a template. Now, when I create a new instance of this site, as you are aware that it will inherit all the lists and properties from the template (in our case 'Tasks List' also).

    My question is - Now will the event handler work (ItemAdded Method) that we wrote earlier? If not then what is the best way around this. If it works .. hurray it saved my day and speed my current project requirements.

    Can you please enlighten on this.

    Many Thanks,

    ReplyDelete
  7. Hi Prakash,

    Thank you very much for the comment. I must say that your question is very good :)

    Question - do event handler work if we do “save site as template”?

    YES – It will work, by doing “save site as template” it will carry event handler functionality also into another site in same server where that dll is already in Same Server! Actyally I tried that and it works for me in same sever .

    Thanks,
    Disha

    ReplyDelete
  8. Hi Disha,

    Thank you for getting back to me on this. Excellent, this really means that Event Handlers are a great feature and saves developers time on rewriting codes for a particular list.

    Another question that new learners (like me) might find useful is

    ' If I create an EventHandler using the code provided, build the project, sign the assembly, add the .dll to the GAC and add a new project within existing project (type class library) and write all the references to sharepoint list and add the EventReceiver syntax.... Now assuming my code works fine and the event is being captured.

    What if I need to update the same project with some new changes (like add a new method or quiet simply change the name of list) then do I just add the changes and click build and the new changes made to the project will be reflected on SharePOint Site or not?'


    It would be useful to know how can developers update these files for major or minor changes. Is this straight-forward like I assume or the process quiet tedious?

    Can you throw some light on this.

    Many Thanks,

    ReplyDelete
  9. Hi Disha,

    Also quickly adding to my previous question.

    Please spend some time looking at this.

    http://saftsack.fs.uni-bayreuth.de/~dun3/archives/getting-started-with-custom-sharepoint-event-receivers/161.html/comment-page-1#comment-334298

    You will observe that this method is remarkably simple as there is no need to do anything other than just writing code for the event handler. Although, I could not get this to work can you still look into the credibility of the method. I think it works (although in my case, I dont know why) don't you think it is easier in terms of achieving functionality I mentioned above for developers.

    I can amend my code and simply click deploy and it updates the changes back to browser.

    What do you think. Awaiting your reply.

    ReplyDelete
  10. Hi Prakash

    If you want to change in your existing event handler let us say add a new method or change list name , then you need to rebuild your solution for new DLL and put DLL into GAC or bin folder(Deploy DLL to proper Place) and just make IISReset.

    Yeap I have looked into the link which you provided me, it is really very nice link.

    Create SharePoint Empty Project and event handler, Post is good but they did not show contents of MyEventReceiverItemEventReceiver\ItemEventReceiver.xml

    May be that’s why it won’t work for you.

    Let me know exactly where you stuck with that example, why you feel that it is not working for you?

    -Disha Shah

    ReplyDelete
  11. Hi Disha,

    Thanks for update on this. First of all, many thanks for offering to help and I really appreciate it. However,the event handler is now working. I did a terrible thing to mistakenly place the code into itemDeleted event where as I should have placed that in itemDeleting event. Then I looked the detailed information you have provided on this post to understand the differences between these events.

    This way of working saves developers enormous amount of time to get things done quickly. However, I must convey to everyone going for this approach that even with this, you still have to sometimes deactivate the feature from site settings and then activate is back on for changes to take place (can be time consuming and clunky). But atleast better than doing everything manually.

    I am currently doing some more work into this and might get back to you with some possible queries.

    Thanks,

    ReplyDelete
  12. Hi Disha,

    Your articles are simple and easy to understand and thanks for posting them.

    Just wondering if you have any information or any web links that you can share with me to achieve this.

    I want to add list item event handlers to a sharepoint site definition - I have a sharepoint site definition which does not pick up the event handlers attached to the lists. How do we put them back on the lists on sharepoint site definition?

    How to do this?

    Thanks,

    ReplyDelete
  13. Prakash

    Thanks for appreciation.

    Now I also have some question like Do you get any error when you attach event handlers to list definition? I think in any list definition schema.xml has “eventreceiver” tag, you can add your events there.

    If you give me error description if you get, I can give you related and specific links for that.

    Still you can refer this link
    http://msdn.microsoft.com/en-us/library/bb736146.aspx

    Hope this helps
    Thanks
    Disha Shah

    ReplyDelete
  14. Hi Disha,

    Following up on my question and your reply. OK, the easiest way to add event handlers on lists as a part of site definition is to create a Visual Studio project for the site using sharepoint solutions generator 2008. Once, inside the project simply add the event handler by - add new item - eventreceiver feature and add your code to the desired methods. However, make sure you delete previous event handlers on the lists from assembly and template/features folder and also reference from central administration. This will make sure that no event is registered twice. When the site is rolled out the eventhandlers work like a charm..

    I see you have recently posted new posts, thanks for that. I will be spending some time to go through those and will get back to you. Keep up the knowledge sharing.

    ReplyDelete
  15. Prakash

    Thanks for taking your time to write about how you solved the problem and sharing about that, it really helps someone. I really appreciate that. Thanks for appreciation.

    Thanks
    Disha Shah

    ReplyDelete
  16. Hi Disha,

    I am from a basics sharepoint background, here trying to create a event handler.. just a simple application to take a default document library and achieve the functionality where application validates the Title field and throws an error if contains spaces in its name up on clicking OK button.. can you tell me where do i start from... is it a console application in visual studio? can you provide me the guide lines or steps to develop and deploy this kind of applications.. much appriciate your response.

    Thanks,
    Naresh

    ReplyDelete
  17. Hi Naresh

    There are so many aspects where you can start as a sharepoint. You can create a webpart, EventHandler, BDC, WorkFlows. Open Visual studio , create a small console application or windows form application and start using every object of Sharepoint Object Model. Like create a list, use spgrid, save /delete/add items to list etc..

    If you start and you stuck at any place please let me know.

    Thanks
    Disha Shah

    ReplyDelete
  18. Hello disha I need your help can you plz let me know your id ? or send me a test mail @ admin@bestindiatimes.com
    thank you very hope you will consider this.

    ReplyDelete
  19. Hi Admin
    I am really glad to assist you, but can you please post your question/concern/issue in the comment section only?
    Thanks & Regards
    Disha Shah

    ReplyDelete
  20. Hi Disha,
    I'm getting the following error message.Can you pls let me know what was the issue.
    "Could not load file or assembly 'EventHandler' or one of its dependencies. The system cannot find the file specified."

    ReplyDelete
  21. Hi Venkat

    The issue is SharePoint does not find the assembly either in GAC or in bin folder of Web Application.

    You need to install Eventhandler DLL to GAC and add that DLL entry as Safe Control in your Web Application web.config file.

    Once you add that entry just do the iisreset.

    Hope this helps!!!

    Thanks & Regards
    Disha Shah

    ReplyDelete
  22. Hi Disha

    i want an event handler to be applied on a list say listA such that whenever a user adds a row, it will copy the items to another list listB.
    I have found a lot of blogs around the web but none of them have a solution which works upfront.

    thanks

    ReplyDelete
  23. Hi

    You can user ListItemEventHandler and use ItemAdded method. In ItemAdded Function write the code for to copy items from ListA to ListB.

    If you have any question , let me know.

    Thanks
    Disha Shah

    ReplyDelete
  24. Hi,
    I have event handler custom code which set metadata from name of file for specific customer id.

    I am using WebDav Client for buld uploading those files and event handlers is not fired or working as intended.

    Please note using event Itemupdated.
    Please advice..

    ReplyDelete
  25. hi Disha,
    I have a question on event Handler.....I have sceduler on a workflow ..If user delete some item from workflow...event handler will check that is there schedule workflow on that item and if yes cancel it.....and also delete item from workflow...How can i accomplish this....

    ReplyDelete
  26. good artical,,
    And i have one question for you.
    if i want to get all the site features and we featrues then wat should i do,means how shuld i do that particular functionality...
    if u have any idea can u please tell me,i am sufferieng wit this functionality for the last 3 days
    Thanks,
    thanuz,
    CSC@India

    ReplyDelete
  27. Hi

    According to my understanding, you want to access all features which are in one site collection via Object Model?

    You can get the all features information via below code.

    SPSite site = SPContext.Current.Site;
    foreach (SPFeature feature in site.Features)
    {

    }

    IF not please provide full explanation so I can provide you solution.

    Thanks
    Disha Shah

    ReplyDelete
  28. Hi Disha,

    I am new to sharepoint development, I have a requirement like, System needs to update a status column in “List A” based on the status column in “List B” with some bussiness logic.
    Status in “List B” will be updated by user manually, kindly provide me some low level suggestions to do this.

    Thanks in advance,
    Ganesh

    ReplyDelete
    Replies
    1. Hi Ganesh

      You can write ItemUpdated event handler on list "ListB", and write the code to update Status column of "ListA".

      But I have one question, you want to update status column of "ListA" for every item or some specific item?

      Let me know if you have some more questions

      Disha Shah

      Delete
    2. Thankyou so much for your reply Disha,

      Explaning you more about my requirement:

      There are 2 Lists namely List A and List B,
      Structure of List A:
      I) List A

      1)Project A
      2)Project B
      3)Project C

      II) List B

      1)Project A
      i)Deliverable 1
      ii)Deliverable 2
      iii)Deliverable 3

      2)Project B
      i)Deliverable 1
      ii)Deliverable 2
      iii)Deliverable 3

      3)Project C
      i)Deliverable 1
      ii)Deliverable 2
      iii)Deliverable 3

      There are status column available for all the deliverables in "List B", based on these status column, we need to update the status column for List Item "Project A" in "List A"


      Business logic behind is:

      1) If all status of deliverables (Deliverable 1,Deliverable 2,Deliverable 3) in "List B" is "Green" for "Project A", then we need to update status "Green" in status column of "Project A" in "List A".

      2) If any one of the status of deliverables (Deliverable 1,Deliverable 2,Deliverable 3) in "List B" is "Yellow" for "Project A", then we need to update status "Yellow" in status column of "Project A" in "List A".

      3) If any one of the status of deliverables (Deliverable 1,Deliverable 2,Deliverable 3) in "List B" is "Red" for "Project A", then we need to update status "Red" in status column of "Project A" in "List A".

      I am expecting an hopeful response from you, if possible kindly share me sample code snippet.

      Thanks in advance.
      Ganesh
      Email: sendtotganesh@gmail.com

      Delete
    3. Hi Ganesh

      After looking into your requirement,you have to write the code for eventhanlder eventname "itemupdated" for "ListB" and write business logic to update status column of "ListA".

      public override void ItemUpdated(SPItemEventProperties properties)
      {

      string status="";
      SPList list = web.Lists["ListA"];
      SPQuery qry = new SPQuery();
      qry.Query ="Continue with the query and provide Project name for which we need to update status column "

      if (list != null)

      {

      //Write the SPQuery from Project name , run against the ListA and get the splistitem from listA.

      }

      if (properties.ListItem["LisbColumnnames"].ToString().ToLower().Contains("Values") )
      //Write the condition which contains or and And here to determine status for ListA

      {
      //Dettemine the Status depends on logic and assign to status variable

      }
      //Now update listsitem["status"] =strstaus and update list

      }

      Hope this helps!!!
      Let me know still if you have any question.
      Disha Shah

      Delete
  29. Hi Disha,
    I am new to sharepoint development
    i want to apply an event handler to listA so that whenver we enter a new item it is copied to listB
    please help me with a working solution
    Thanks in advance,

    ReplyDelete
    Replies
    1. Hi Mouna

      Here is my post where you will find the exact code which you should written in ItemAdded EventHandler.

      http://dishasharepointworld.blogspot.com/2012/03/how-to-copy-listitem-from-one-list-to.html

      If you have any questions, Please let me know

      Thanks
      Disha Shah

      Delete
  30. Hello Disha ,
    I'm a student and I have to do a project by using Sharepoint but I have difficulties
    I want to get the value of item from field choice in an event receiver but I can't do it
    Please help me
    Thanks a lot :)

    ReplyDelete
    Replies
    1. Hi Chaima

      If you have Choice Field as single Choice then this code work well for Event Handler.

      SPFieldChoice ChoiceField = (SPFieldChoice) properties.ListItem.Fields["ChoiceField"];
      string SelectedValue = ChoiceField.GetFieldValueAsText(properties.List.Fields["ChoiceField"]);


      If you need more help please drop a comment

      Thanks
      Disha Shah

      Delete
  31. Hi Disha,

    this code of Choice Field doesn't work .I always have this error :Object reference not set to an instance of an object.

    Thanks

    ReplyDelete
    Replies
    1. Hi Ghada


      I have written this code in ItemAdded Event in EventHandler.
      SPFieldChoice ChoiceField = (SPFieldChoice)properties.ListItem.Fields["Status"];

      string SelectedValue = ChoiceField.GetFieldValueAsText(properties.ListItem["Status"]);

      Could you tell me in which eventhanlder you are trying to retrieve value?

      Thanks Disha

      Delete
  32. Thanks Disha
    But I doesn't work , I have this erreur 'Object reference not set to an instance of an object' :(
    I want to get the selected item value from the choice field

    ReplyDelete
    Replies
    1. Hi Chaima

      I have written this code in ItemAdded Event in EventHandler.Slightly change before the above code.

      SPFieldChoice ChoiceField = (SPFieldChoice)properties.ListItem.Fields["Status"];

      string SelectedValue = ChoiceField.GetFieldValueAsText(properties.ListItem["Status"]);

      It works fine for me.Could you tell me in which eventhanlder you are trying to retrieve value?

      Thanks
      Disha Shah

      Delete
  33. Hi Disha ,
    Please help ,I have another problem
    i want if you click on the button BUSINESS another form appeared as soon as he chooses a profession, a grid is added to the first form and the data corresponding to this business will be displayed
    Thaaaaaanks a lot

    ReplyDelete
    Replies
    1. Hi

      Well by looking at description of your Problem I have some questions
      Like
      Where the Professions are has been stored?
      On first form you have "Business" Button and also Profession.

      If Professions are stored inside the List you can use Query Filter Webpart or write Custom Webpart to show the business related information.

      Please provide detail information So I can provide the right guidance.

      Thanks
      Disha Shah

      Delete
  34. Hi,

    I have a NewForm (his name :Departement)in which there are many columns and a button ,when I clicked on the button another NewForm appeared in which I found a lookupfield and when I selected an item from this lookupfield ,all the information related to this item where displayed in the first NewForm (his name :Departement) in a grid
    I have not idea to do it :(
    Please help me
    Thanks

    ReplyDelete
  35. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. Hi Disha,
      Please I wanna know how can I create a button in the ribbon which become visible if I select an item of the list and this button must display a NewForm related to this selected item .

      In fact, when I select an item I should retrieve the value of column "code" and from this value I know which newForm should be opened .

      Thanks

      Delete
    2. Hi

      To customize ribbon and add a new button please look at the following link which gives step by step instructions.

      http://aarebrot.net/blog/2010/09/adding-a-custom-button-to-the-ribbon-using-a-feature-in-sharepoint-2010/

      Thanks
      Disha Shah

      Delete
  36. Hi

    Thanks for your help Disha I have created the button and it works well.But my problem is that I wanna that when I select an item and click in the button, the list reliated to this item apprears. In fact, I have associated for each item added a list which will be created automatically .By this button I wanna display the list associated to this selected item.
    I hope that you have understand my problem
    Thanks

    ReplyDelete
  37. Hi Disha,

    I am very new to the Sharepoint; please help me out.

    I have created a customList and I am accessing the items from that list externaly using url created with unique ID of that item.

    I want to write some code on the loding event of the editItem page of that list; when I am trying to access and edit that item by clicking the url created.

    Your help will be appriciable.

    Thanks

    ReplyDelete
  38. Ashish

    What you want to do on Load of EditItem Page?

    If you want to customize the Edit Page you could do with the SharePoint Designer or add content editor webpart on the page and add javascript or Jquery.

    Would you please let me know what you want to achive?

    Thanks
    Disha Shah

    ReplyDelete
  39. Hello Disha,
    Nice Article as usual.
    I need a small favor, Last time I have read an article by you in some other blog. In which you have mentioned the method how to Add a custom action link to people and group list to export the data into a spreadsheet.
    If you still have a same document with you the plz send it to me at rudreshtewari@gmail.com


    Thanks & Regards,
    Rudresh

    ReplyDelete
  40. Hello Disha,

    Let me start by saying thank you for coming up with this method as I'm thinking (hoping) it will be exactly what I need. My question to you is do you think it will work well as a many to 1 type of situation. I have several lists feeding up to 1 master. If an item is deleted from any of those lists, I'll need to remove it from the master.

    Thanks in advance for your hard work

    ReplyDelete
    Replies
    1. Hi Stanley

      Thank you for appreciation!!!

      Yes it will work for multiple lists as you can see I have written for 2 lists already so you just need to call this function CheckReferencedata for the number of the lists you hvae.

      If you have any issue, drop comment.

      Thanks
      Disha Shah

      Delete