HOWTO : Create a Site with a custom template through code and assign specific user security (User has no rights to create a site).
Imagine the following scenario. In your site collections visitors need to be able to create 1 type of sites. When they create that type of site (with a custom template) they need to become the administrator of that site, as well as the people maintaining the site collection.
How do we do that in SharePoint? We create a site while running with Elevated Privileges, let it inherit the rights of the Site Collection. Once the site is created, we break the inheritance and add specific user rights for that user.
First of all we will be creating a function that accepts a few strings that we need to create the site.
The parentSiteUrl is the url in which we will be creating the site, the requested siteUrlRequested is the url we will be creating the site in, the siteTitle is the title we will be giving to the site, and the siteTemplateName is the name of the Custom Template we will be using.
Ok, let’s write the code to create our site in our parentsite. In the GetCustomWebTemplates functions we will be getting the custom web template list corresponding the language of the site. In that list we take the template as specified in the parameter of our function (siteTemplateName). As we can’t be sure that the user has checked if a site url already exists we increase a counter till we find a free siteUrl (this is not mandatory, you can also raise an error on the Exists boolean).
With this code our site will be created by making use of the custom template. We are running with Elevated Privileges as the user does not have any permissions to create a subsite. In the using statement of myWeb we will be adding the security changes.
With BreakRoleInheritance we break the inheritance of the rules. We do this to be able to add the user to the security of that specific site. We are breaking the security afterwards because we want to make sure that the existing security on the site is copied as well. With the EnsureUser statement we make sure the user exists in that site. The SPRoleDefinition isn’t necessary, but I’m using it to make sure that my code runs on multilingual systems. You could use:
but in a multilingual environment that RoleDefinition isn’t called Contributor. That’s why I will first create a SPRoleDefinition object to make sure that whatever Contributor is called will return the correct name in my SPRoleAssignment. I add the roledefinition to the assignment and then I add the user/role link to the site. Once you have implemented all this your code should look like this:
Calling the function can be done like this (Web is the SPContext.Current.Web object).
The following code shows you how to get the last item of an ID in a list. Warning, this code gets you the last item from that list meaning that if you use this code to get the last item you added, it will go wrong if someone adds an item between you adding it and executing this query. In that case I advise you to get a unique identifier that you add to each item and get the item by that id.
As it’s been a while since I did some real Windows development I started building a tool that makes it easier to manage content types during a development cycle (changes to content types, changes of documententation to those content types, linked list definitions, …) One of the required abilities is to be able to load an xml file *duh*. As I wanted people to get to the initial directory of the application I used:
OpenFileDialog ofd = new OpenFileDialog();
ofd.Multiselect = false;
ofd.Filter = “XML Files|*.xml”;
ofd.InitialDirectory = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase);
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
txtContentTypeLocation.Text = ofd.FileName;
To my great surprise, that did not work. I looked around on the web but didn’t really find a solution, while in debug the folder was giving the correct information. However, when I changed it into:
ofd.InitialDirectory = Environment.CurrentDirectory;
everything worked fine. I guess it’s a bit picky on how it gets the folder information…