Question

I am working on SharePoint 2013 team site collection, and I have the following architecture -

  1. A team site collection which contain 15 sub sites. Each subsite represents one of our customers.
  2. On each subsite I have an issue tracking list.
  3. All the issue tracking lists inside the subsite share the same permission and the same content type.
  4. But on each subsite’s tracking list, the “assigned to” column (at the list level) is linked to a unique user group representing the customer’s client account managers. Group name is "Customer name client managers"

Now I have the following requirements:-

  1. If the user how adds an issue tracking list item is defined inside the related “Customer name client managers” group, then to set a column named “Important” to Yes.
  2. To test this I wrote an event receiver , and I set it as follow:-

    • I specify the site url to be equal to a subsite url.
    • Specific to have a farm solution
    • The event receiver type is “List item events”
    • Which will trigger when an item was created .
  3. Now the above worked well on the intended subsite. But i will be facing these limitations:-

I will have to apply 11++ different event receivers representing 11 different sub-sites, since I have deploy the event receiver to the related sub-site url.

Also inside the event receiver I have explicitly defined the related group name "CustomerA" in the below code. So my question is if there is a way to improve my approach to allow reusing the same event receiver among all the sub-sites. For example to apply the event receiver to the site content type instead to the subsite, and inside the event receiver to dynamically select the related group name based on the current subsite? Where I can name the group to be equal to the subsite name,, In this case I will have a single event receiver which should work on all the subsites ??

here is the code for the event receiver:-

 public override void ItemAdded(SPItemEventProperties properties)
            {
                base.ItemAdded(properties);
                bool findany = false;
                using (SPSite site = new SPSite(properties.SiteId))
                {
                    using (SPWeb web = properties.OpenWeb())
                    {
                        try
                    {

                        SPListItem currentItem = properties.ListItem;
                        SPUser user = properties.Web.CurrentUser; 

                        SPGroup group = web.SiteGroups["CustomerA"];
                        foreach (var user2 in group.Users)
                        {
                            if (user2.ToString() == user.ToString())
                            {
                                currentItem["Important"] = "Yes";
                                currentItem.SystemUpdate();
                                findany = true;
                                break;
                            }

                        }
                        if (!findany)
                        {
                            currentItem["Important"] = "No";                            
                            currentItem.SystemUpdate();
                        }

                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
            }  
        }
Was it helpful?

Solution

If I understood the need, I think you can do the following:

  • Associating the event receiver to the content type (below I'll show you how)
  • Get a reference to the subsite using SPWeb web = properties.OpenWeb();
  • Perhaps you create a list in the root site to store the relationship between the group name and the subsite

Example of how to associate the event to a content type

public static void addEventContentType(string clase, SPContentType tipoContenido, string ensamblado, SPEventReceiverType eventReceiverType, SPEventReceiverSynchronization sincro)
{
 SPEventReceiverDefinition eventReceiver = tipoContenido.EventReceivers.Add();
 eventReceiver.Synchronization = sincro;
 eventReceiver.Type = eventReceiverType;
 eventReceiver.Assembly = ensamblado;
 eventReceiver.Class = clase;
 eventReceiver.HostType = SPEventHostType.ContentType;
 eventReceiver.Update();
}

Sample use:

public static void asociarEventosGovernance(SPSite sitio)
{
 SPWeb mi_web = sitio.RootWeb;
 string ensambladoGovernance = typeof(EventReceiverGovernance).Assembly.FullName;
 string claseGovernance = typeof(EventReceiverGovernance).FullName;
 SPContentType tipoContenidoGovernance = mi_web.ContentTypes["Governance"];
 Internal.addEventContentType(claseGovernance, tipoContenidoGovernance, ensambladoGovernance, SPEventReceiverType.ItemAdded, SPEventReceiverSynchronization.Synchronous);
}

If you need more information, please let me know.

OTHER TIPS

You can create a List called "Parameters" in every site where you can set those particular options (it can be a SiteGroup Name, a Content Type Name, an URL, a ListName, etc.)
The structure can be something like:
Parameter List Structure

You can set every parameter you need to be different in each site/subsite Setting Parameters

Of course, you need to code your event receiver to read values from this list everytime you want, you can use the snippet below:

            SPQuery query = new SPQuery();
            query.RowLimit = 1;
            query.Query =
                    @"
                <Where>
                    <Eq>
                        <FieldRef Name='" + __column + "' /> " +
                            "<Value Type='" + list.Fields.GetFieldByInternalName(__column).Type + "'>" + __value + "</Value>" +
                        @"
                    </Eq>
                </Where>";             
            SPListItemCollection listItems = list.GetItems(query);

Where list is your "Parameters" collection, this may not be efficient but you can tune it a little by setting the RowLimit = 1 in the query.

Hope to help.

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top