0

I am working on SharePoint server 2013 web application. And I need to create an event receiver on my lists items. The event receiver will check if the user who create an item is within a specified user group and update some items fields accordingly. Here is the event receiver I am planning to have:-

public override void ItemUpdated(SPItemEventProperties properties)
        {
            DisableEventFiring();
            base.ItemUpdated(properties);
            bool findany = false;

            using (SPSite site = new SPSite(properties.SiteId))
            {
                using (SPWeb web = properties.OpenWeb())
                {
                    try
                    {
                        web.AllowUnsafeUpdates = true;
                        SPListItem currentItem = properties.ListItem;


                        SPGroup group = web.SiteGroups[webname];

                        }
                        SPUser user = properties.Web.CurrentUser;


                        if (currentItem["Team"] == null || currentItem["Team"] == string.Empty)
                        {
                            foreach (var user2 in group.Users)
                            {
                                if (user2.ToString() == user.ToString())
                                {
                                    currentItem["Team"] = "CM";


                                    findany = true;
                                    break;
                                }

                            }
                            if (!findany)
                            {
                                currentItem["Team"] = "IT";
                                //currentItem["Action"] = "Item Added";
                                currentItem.SystemUpdate();
                            }
                        }



                        currentItem.SystemUpdate();

                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                    finally
                    {
                        EnableEventFiring();
                    }

                }
            }
        }

Now my problem is how I can re-use my event receiver on multiple subsites and list. Currently I have the following architecture for my web application:-

  • I have a team site collection on the root http://servername/
  • Inside it I have a team sub-site http://servername/customers/
  • Inside the /customers/ subsite I have many subsites; http://servername/customers/customerA , http://servername/customers/customerB , etc…
  • Inside each of the customerA, customerB , etc subsites I have 4 issue tracking lists.
  • Each list uses different site content type.
  • Now the event receiver I want to use will be targeting all the customers’ subsites. And only on one issue tracking list which is named “Tracking”.
  • In another words I want I event receiver to be targeting all the lists named “Tracking” found inside all the subsites under the /customers/ sub site. Or to be targeting all the lists “whatever are their name” that uses a site content type named “CustomersTracking”.

So I want to target the event receiver to a group of lists which have these things in common :-

  • Have the same list name (Tracking) and are under the parent subsite /customers/
  • Share the same site content type and all are under the parent subsite /customers/

So can anyone advice how I can target my event receiver to those lists only?

Thanks

1

You can deploy your event receiver as a Web scoped feature. As you say that all your lists in your subsites have the same name (Tracking)- you can open the elements.xml file for your event receiver and change the Receivers tag as below

<Receivers ListUrl="Lists/Tracking">

You can activate this feature on each subsite whenever it gets created using the SPWebEventReceiver WebProvisioned method

  • thanks a lot for the reply.. but can you please provide more details . now when i create a new event receiver inside visual studio. i will be prompted to enter the site url , so which url i should use ? the site collection url "servername" or the subsite url which is "+servername/customers_"?? second question from the scope drop down list for the feature should i select Web,Site, Farm or web application ? and why ? – john Gu Oct 10 '16 at 18:00
  • also can you please adivce why you want me to define the scope of the event receiver to be Web?as if i define the scope to be "Site" i will get only one feature at the site collection level instead of multiple features at the subsites. Now I defined the following the following settings; I select the feature scope to be “Site” from the scope drop down list. and inside the elements.xml I define the following "ListUrl="Lists/tracking"". Now the results was that I got only one activated feature at the site collection level, – john Gu Oct 11 '16 at 0:34
  • but I have noted that the event receiver will be fired whenever an item is updated and not only the items inside the "tracking" lists as defined inside the elements.xml file? Not sure why ? – john Gu Oct 11 '16 at 0:34
  • can you please adivce more on my comments if you can ?thanks – john Gu Oct 11 '16 at 12:28
  • 1
    By having a web scope feature you can ensure that any newly created sites have this functionality enabled on creation. You can check using Powershell if any event recievers are attached to a list for your query regarding ER firing on lists other than the tacking list. – HarryB Oct 11 '16 at 13:45
0
  • If you need to apply it to a specific one list, do it as the @HarryB suggest <Receivers ListUrl="Lists/ListView" >. But I need to add more calarafication where this URL does not include the subsite URL.

    • For Example: the List URL at your subsite is http://servername/customers/customerA/Lists/ListView so you should get only Lists/ListView
  • If you need to apply it to all lists that have Issue Tracking content type, try to modify your Element.xml that located at your project within solution explorer to ListTemplateId="1100" as shown below

enter image description here

  • If you need to apply it to specific multiple lists that have Issue Tracking content type ( this option is your case),

    • Try to modify your Element.xml at your solution explorer to ListTemplateId="1100"
    • And at your code check if the current list ID = your list Id then execute your code as the following

Final Code:

     public override void ItemUpdated(SPItemEventProperties properties)
      {
        DisableEventFiring();
        base.ItemUpdated(properties);
        bool findany = false;

        using (SPSite site = new SPSite(properties.SiteId))
        {
            using (SPWeb web = properties.OpenWeb())
            {
                try
                {
                    string[] ListIDs = { "{e9b842e6-0030-456f-b543-46c837a90c85}", "{e9b842e6-0030-456f-b543-46c837a90c77}" };
                    bool found = false;
                    string currentListID = properties.ListId.ToString();
                    foreach (string x in ListIDs)
                     {
                        if (currentListID.Contains(x))
                           {
                                found = true;
                           }
                     }

                    if (found == true)
                    {

                    web.AllowUnsafeUpdates = true;
                    SPListItem currentItem = properties.ListItem;


                    SPGroup group = web.SiteGroups[webname];


                    SPUser user = properties.Web.CurrentUser;


                    if (currentItem["Team"] == null || currentItem["Team"] == string.Empty)
                    {
                        foreach (var user2 in group.Users)
                        {
                            if (user2.ToString() == user.ToString())
                            {
                                currentItem["Team"] = "CM";


                                findany = true;
                                break;
                            }

                        }
                        if (!findany)
                        {
                            currentItem["Team"] = "IT";
                            //currentItem["Action"] = "Item Added";
                            currentItem.SystemUpdate();
                        }
                    }



                    currentItem.SystemUpdate();

                }}
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    EnableEventFiring();
                }

            }
        }
    }

Replace your List ID's at this array string[] ListIDs = { "{e9b842e6-0030-456f-b543-46c837a90c85}", "{e9b842e6-0030-456f-b543-46c837a90c77}" }; based on your list ID of your lists.

To get list ID

  • Go to list > list setting at this section in your url get this bold ID listedit.aspx?List=%7BE9B842E6%2D0030%2D456F%2DB543%2D46C837A90C85%7D

  • And replace %2D = - and %7D = }

  • thanks for your reply. but there are still some missing points.1) i did not get your idea when you said "But I need to add more calarafication where this URL does not include the subsite URL" i did not understand what do you mean exactly? 2) second point regarding deploying the solution for all the subsites one by one by changing the url, i think this should not be the case. – john Gu Oct 10 '16 at 22:33
  • as when i test my feature i select the site url to be "servername/customer/CustmerA" where the feature got activated inside CustomerA subsite but at the same time the feature got added(but in deactivated status) at the other subsites "CustomerB", "CustoemrC",etc... so i do not think i need to re-deply the solution for each subsite one by one!! and also if i redeploy the same feature i will get an error that the same feature id already exists inside the farm ... – john Gu Oct 10 '16 at 22:34
  • for first comment I response to your comment at harryB when you tell him am I need to add the full URL of sub site or not ?, so I reply to you regarding this point no need for this , no need to add the URL of subsite, – Mohamed El-Qassas MVP Oct 10 '16 at 23:33
  • for the second comment , you are right but what I mean the lists in your second site have a different ID so you should create a new solution with new feature and replace your list id based on the id of the list in your second subsite , meanwhile I remove this from my answer to don't confuse you, and you are free for how to do this !!! but this my suggestion that i tried it before on the same situation and I think it now clear , what I was mean ? – Mohamed El-Qassas MVP Oct 10 '16 at 23:34
  • anyway I give you the solution to how to apply it to specific lists based on the issue tracking content type in the final code ,so why you don't comment for this :) are you tried this ?!! I provide you all options with event receiver and this the core question hope it helps – Mohamed El-Qassas MVP Oct 10 '16 at 23:35

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.