This post has been migrated from www.experimentsincode.com, we apologise if some of the images or content is missing

This post has been migrated, original date 06 Oct 2009 Ever find yourself thinking there must be a quicker/nicer way to run code with elevated permissions instead of the standard:
//run this block as System Account
Guid siteId; //get site id
Guid webId; //get web id
SPSecurity.RunWithElevatedPrivileges(delegate()
  {
    using (SPSite site = new SPSite(siteId))
    {
       using (SPWeb web = site.OpenWeb(webId)){
	 //DO some work
       }
    }
  }
Instead of writing all this I have written a wrapper class:
    public class SPElevatedPermissions : IDisposable
    {
        public delegate void CodeToRunElevated();

        private SPWeb _elevatedWeb;
        private SPSite _elevatedSite;

        public SPWeb ElevatedWeb { get { return _elevatedWeb; } }
        public SPSite ElevatedSite { get { return _elevatedSite; } }

        public SPElevatedPermissions(SPWeb originalWeb)
        {
            Guid siteId = originalWeb.Site.ID;
            Guid webId = originalWeb.ID;

            SPSecurity.RunWithElevatedPrivileges(() =>
            {
                _elevatedSite = new SPSite(siteId);
                _elevatedWeb = _elevatedSite.OpenWeb(webId);

            });
        }

        public void RunCode(CodeToRunElevated secureCode)
        {
            SPSecurity.RunWithElevatedPrivileges(() =>
            {
                secureCode();
            });
        }

        #region IDisposable Members

        public void Dispose()
        {
            if (_elevatedWeb != null) _elevatedWeb.Dispose();
            if (_elevatedSite != null) _elevatedSite.Dispose();
        }

        #endregion
    }
As you can see from above in the constructor we create the elevated webs and site, we can then use them as below without needing the code to be wrapped in the SPSecurity.RunWithElevatedPermissions method because the majority of code just needs access to a web/site that is the context of the elevated user:
SPWeb web = SPContext.Current.Web;

using (SPElevatedPermissions elev = new SPElevatedPermissions(properties.OpenWeb()))
{
  SPList  list = elev.ElevatedWeb.List[listId];
  //do other work
}
However if you still need for some reason to actually run the code itself in elevated mode we can call the RunCode() method:
SPWeb web = SPContext.Current.Web;

using (SPElevatedPermissions elev = new SPElevatedPermissions(properties.OpenWeb()))
{
  elev.RunCode(()=>{
    SPList  list = elev.ElevatedWeb.List[listId];
    //do other work
  });
}
We can also run multiple code blocks without worrying about having to instantiate the elevated web and site again or worrying about their scoping:
SPWeb userWeb = SPContext.Current.Web;

using (SPElevatedPermissions elev = new SPElevatedPermissions(userWeb))
{
  elev.RunCode(()=>
  {
	SPList  list = elev.ElevatedWeb.List[listId];
	//do other work
  });
  //do something else here
  SPList userList = userWeb.List[listId];

  SPList anotherList = elev.ElevatedWeb.List[listId2];
  //process something else
}
comments powered by Disqus