3

I am working on SharePoint Server 2013 Enterprise, and I have implemented the following event receiver which is scoped at the Web level, and will fire when a list item is added:-

public class EventReceiver1 : SPItemEventReceiver
    {
        /// <summary>
        /// An item is being added.
        /// </summary>

        public override void ItemAdded(SPItemEventProperties properties)
        {

            base.ItemAdded(properties);
//code goes here
 SPWeb newSite = spCurrentSite.Webs.Add(curItemSiteName, curItemSiteName, "subsite was added automatically", Convert.ToUInt16(1033), webTemplate, false, false);

Now as shown above, the event receiver will create a new sub-site when a list item is added. Now the above event receiver will work fine when users with "Full Control" Permission add an item (users who can create sub-sites), but if a user with Contribute permission adds a new list item , the event receiver will raise the following exception :-

Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

when trying to create the new sub-site, since a contributor user can not create subsites. So can anyone advice if there is a way to force my event receiver to bypass the permission checking when creating a new sub-site?

Here is my full Event Receiver code:--

 public override void ItemAdded(SPItemEventProperties properties)
        {

            base.ItemAdded(properties);



            // Get the web where the event was raised

            SPWeb spCurrentSite = properties.OpenWeb();



            //Get the name of the list where the event was raised         

            String curListName = properties.ListTitle;



            //If the list is our list named SubSites the create a new subsite directly below the current site

            if (curListName.ToLower() == "projects")
            {

                //Get the SPListItem object that raised the event

                SPListItem curItem = properties.ListItem;

                //Get the Title field from this item. This will be the name of our new subsite

                String curItemSiteName = properties.AfterProperties["Title"].ToString();

                //Get the Description field from this item. This will be the description for our new subsite

                //string curItemDescription = properties.AfterProperties["Description"].ToString();

                //Update the SiteUrl field of the item, this is the URL of our new subsite

                //properties.AfterProperties["SiteUrl"] = spCurrentSite.Url + "/" + curItemSiteName;



                // Get the rootweb where we will find the available templates

                SPWeb rootWeb = spCurrentSite.Site.RootWeb;

                //Get all the webtemplates available on this site collection

                SPWebTemplateCollection webTemplates = rootWeb.GetAvailableWebTemplates(1033);

                SPWebTemplate webTemplate = null;

                String webTemplateName = "NewProject"; //this is the name of the template we will use

                String webTemplateSearchName = "";


                //Get the template based on name. In this example 'ProjectTemplate'

                //Loop through the available templates
                for (int i = 0; i < webTemplates.Count; i++)
                {

                    webTemplateSearchName = webTemplates[i].Name.ToString();


                    if (webTemplateSearchName.Contains(webTemplateName))
                    {
                        //when we have found the matching template,set webTemplate to the foundt template and exit the if loop
                        webTemplate = webTemplates[webTemplateSearchName];

                        break;

                    }

                }

                //Create the subsite based on the template from the Solution Gallery

                SPWeb newSite = spCurrentSite.Webs.Add(curItemSiteName, curItemSiteName, "123", Convert.ToUInt16(1033), webTemplate, false, false);

                //Set the new subsite to inherit it's top navigation from the parent site, Use false if you do not want this.

                newSite.Navigation.UseShared = true;

                newSite.Close();





            }

        }


    }
4

try it as below:

public override void ItemAdded(SPItemEventProperties properties)
{
    base.ItemAdded(properties);

    SPUserToken systemAccountUserToken = SPContext.Current.Site.SystemAccount.UserToken;
    using (SPSite elevatedSite =new SPSite(properties.SiteId,systemAccountUserToken)) 
    {
        SPWeb newSite = elevatedSite.AllWebs.Add(curItemSiteName, curItemSiteName, "subsite was added automatically", Convert.ToUInt16(1033), webTemplate, false, false);
    }
}

Or using this method:

public override void ItemAdded(SPItemEventProperties properties)
{
    base.ItemAdded(properties);
    SPSecurity.RunWithElevatedPrivileges(delegate()
    {
         using (SPSite site = new SPSite(properties.SiteId))
         {
            SPWeb newSite = site.AllWebs.Add(curItemSiteName, curItemSiteName, "subsite was added automatically", Convert.ToUInt16(1033), webTemplate, false, false);
         }
    });
}

The above code will run with elevated permissions.

Try the below full code:

public override void ItemAdded(SPItemEventProperties properties)
{
    base.ItemAdded(properties);

    SPSecurity.RunWithElevatedPrivileges(delegate()
    {
        using (SPSite site = new SPSite(properties.SiteId))
        {
            using (SPWeb web = site.OpenWeb())
            {
                String curListName = properties.ListTitle;

                //If the list is our list named SubSites the create a new subsite directly below the current site                                                

                if (curListName.ToLower() == "projects")
                {

                    //Get the SPListItem object that raised the event

                    SPListItem curItem = properties.ListItem;

                    //Get the Title field from this item. This will be the name of our new subsite

                    String curItemSiteName = properties.AfterProperties["Title"].ToString();

                    //Get the Description field from this item. This will be the description for our new subsite

                    //string curItemDescription = properties.AfterProperties["Description"].ToString();

                    //Update the SiteUrl field of the item, this is the URL of our new subsite

                    //properties.AfterProperties["SiteUrl"] = spCurrentSite.Url + "/" + curItemSiteName;

                    // Get the rootweb where we will find the available templates

                    SPWeb rootWeb = web.Site.RootWeb;

                    //Get all the webtemplates available on this site collection

                    SPWebTemplateCollection webTemplates = rootWeb.GetAvailableWebTemplates(1033);

                    SPWebTemplate webTemplate = null;

                    String webTemplateName = "NewProject"; //this is the name of the template we will use

                    String webTemplateSearchName = "";


                    //Get the template based on name. In this example 'ProjectTemplate'

                    //Loop through the available templates
                    for (int i = 0; i < webTemplates.Count; i++)
                    {

                        webTemplateSearchName = webTemplates[i].Name.ToString();


                        if (webTemplateSearchName.Contains(webTemplateName))
                        {
                            //when we have found the matching template,set webTemplate to the foundt template and exit the if loop
                            webTemplate = webTemplates[webTemplateSearchName];

                            break;

                        }

                    }

                    //Create the subsite based on the template from the Solution Gallery

                    SPWeb newSite = web.Webs.Add(curItemSiteName, curItemSiteName, "subsite was added automatically", Convert.ToUInt16(1033), webTemplate, false, false);
                    //Set the new subsite to inherit it's top navigation from the parent site, Use false if you do not want this.

                    newSite.Navigation.UseShared = true;

                    newSite.Close();

                }

            }
        }                   

    });
}
  • 2
    Big heads-up with using SPContext in event receivers. It will be null if the code is not called from a web process (like if called from a console application or timer job) – Robert Lindgren Dec 4 '16 at 10:39
  • 1
    @johng correct! You should be able to get the site and web from the properties instead – Robert Lindgren Dec 4 '16 at 16:24
  • 1
    check updated full event receiver code now. Have also added @RobertLindgren 's suggestion to use properties – Gautam Sheth Dec 5 '16 at 6:21
  • 1
    @johnG - i think it should work just fine. Havent tested it as my VM crashed. Can you test the code ? let me know if you face the same issue again, will recreate the it tomorrow as i would need to new environment. – Gautam Sheth Dec 5 '16 at 12:29
  • 1
    @johnG - my bad. You were correct regarding the spweb object. Have updated the code. Should work with elevated permissions now. – Gautam Sheth Dec 5 '16 at 14:08

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.