Home > Development, SharePoint > Self Service Site Creation through code

Self Service Site Creation through code

Note: This post only looks at SPSite.SelfServiceCreateSite from the object model.

The challenge

In most cases site collections are created by administrators with farm admin permissions, but in some cases you want to provide your users the ability to create site collections. Still a lot of developers use methods like the SPSite.Add() to create the site collections, which are actually meant for administrator task only and require you to have farm level permissions. Well, being a developer that is easily solved. Just add the web application pool account to the farm administrators and you can get the necessary permissions by simply using a SPSite.SelfServiceCreateSite method. Using this method you can allow regular users to create site collections, without giving them farm level permissions. To make this work there are two settings you must take into account: SPSecurity.RunWithElevatedPrivileges. Well, that’s something we DON’T want. Normal users should never get farm level permissions, simply because they always find a way to create havoc.

The solution

The solution is actually really simple. Microsoft provides us with the

  1. Enable Self-Service Site Management
    This allows the users to actually create site collections using the SPSite.SelfServiceCreateSite

               Figure 1: Enable Self-Service Site Management

  1. Have multiple managed paths
    Make sure you have another managed path as the (root) managed path. Sites should be created by default for most of the Web Applications, but you’ll need a managed path to be able to create new site collections.

               Figure 2: Create multiple managed paths

The implementation

For this example I created a WebPart which allows an user to create a new site collection. Within the code of the solution you’ll also find some other nice pieces of code, for example:

  • How to check if “Self-Service Site Management” is enabled
  • How to check if multiple managed paths are created
  • How to load the drop down list with the available managed paths (SPWebApplication.Prefixes)
  • How to load the drop down list with the available web templates (SPSite.GetWebTemplates(uint))
  • How to make use of SPLongOperation to show a nice progress window.

090909_2012_selfservice3

Figure 3: Example WebPart for the use of SelfServiceCreateSite

Once the information of the new site collection is entered and the user presses the Submit button, the site collection will be created. This might take a couple of seconds and during this time you don’t want to let the user click again on the submit button. The second time there might already be a site on the URL which is provided (since the user clicked on the button before), and they will get an exception. To prevent this problem, a progress screen is shown.

090909_2012_selfservice4

Figure 4: Creation of Site Collection is in progress

Once the site collection is created, the user will be redirected to the newly created site.

090909_2012_selfservice5

Figure 5: Newly generated Site Collection

The code

The following function shows the use of the SPSite.SelfServiceCreateSite. Basically it’s just calling the function with the correct variables, but there are a couple of pitfalls you should take into account

/// <summary>
/// This function will create a site collection using <see cref=”SPSite.SelfServiceCreateSite”/>
/// </summary>
/// <param name=”relativeSiteUrl”>
/// The relative url of a site. This should include a managed path since the root site
/// collection already exist. Example “sites/testsite”
/// </param>
/// <param name=”title”>The title of the new site</param>
/// <param name=”description”>The description of the new site</param>
/// <param name=”webTemplate”>The web template name</param>
/// <param name=”secondarySiteCollectionAdministratorLogin”>
/// The user login account of the secondary site collection administrator
/// </param>
/// <param name=”secondarySiteCollectionAdministratorName”>
/// The name of the secondary site collection administrator
/// </param>
/// <param name=”secondarySiteCollectionAdministratorEmail”>
/// The email address of the secondary site collection administrator
/// </param>
/// <returns>
/// The newly create <see cref=”SPSite”/> or null when an error has occured.
/// </returns>
private SPSite CreateNewSiteCollection(string relativeSiteUrl,
        string title,
        string description,

        string webTemplate,

        string secondarySiteCollectionAdministratorLogin,

        string secondarySiteCollectionAdministratorName,

        string secondarySiteCollectionAdministratorEmail)
{
    SPSite newSiteCollection = null;

    // The creation will only work if you set the primary administrator is set to the current user

    string primarySiteCollectionAdministratorLogin = SPContext.Current.Web.CurrentUser.LoginName;

    string primarySiteCollectionAdministratorName = SPContext.Current.Web.CurrentUser.Name;

    string primarySiteCollectionAdministratorEmail = SPContext.Current.Web.CurrentUser.Email;

    // Small change you want to set this variable on a different value as the root site collection

    uint localIdentifier = (uint)SPContext.Current.Web.Locale.LCID;
   
    try
   
{
        // Make sure we are at the root site collection

        using (SPSite rootSite = new SPSite(GetAuthorityUrl(SPContext.Current.Web.Url)))
       
{
            // If no secondary site collection administrator is provided, use null values

            // in stead of an empty string. Otherwise an Exception will be thrown.

            if (string.IsNullOrEmpty(secondarySiteCollectionAdministratorLogin))
               
newSiteCollection = rootSite.SelfServiceCreateSite(
                       
relativeSiteUrl,
                       
title,
                       
description,
                       
localIdentifier,
                       
webTemplate,
                       
primarySiteCollectionAdministratorLogin,
                       
primarySiteCollectionAdministratorName,
                       
primarySiteCollectionAdministratorEmail,
                       
null,
                       
null,
                       
null);
            else
           
{
                // When a secundary site collection has been provided, add this account as a

                // secundary site collection administrator
               
newSiteCollection = rootSite.SelfServiceCreateSite(
                       
relativeSiteUrl,
                       
title,
                       
description,
                       
localIdentifier,
                       
webTemplate,
                       
primarySiteCollectionAdministratorLogin,
                       
primarySiteCollectionAdministratorName,
                       
primarySiteCollectionAdministratorEmail,
                       
secondarySiteCollectionAdministratorLogin,
                       
secondarySiteCollectionAdministratorName,
                       
secondarySiteCollectionAdministratorEmail);
            }
        }
   
}
   
catch
   
{
        // You can implement some logging here. It can for example happen that you provide
        // a URL of a site that already exist, a template that not exist etc.
   
}

     return newSiteCollection;
}

The pitfalls

There are a couple of pitfalls you need to be aware of when you use SPSite.SelfServiceCreateSite. There are probably more, but these issues I encountered:

  1. Current user needs to be set as primary administrator
    SPSite.SelfServiceCreateSite will only work if you set the current user as the primary site administrator. When you want to allow users to create a site “on behalf” of somebody else, that is still possible. You’ll have to create the site with the current user as the primary site collection administrator and once it is created, change the owner (don’t forget, after making that change you might not be able to let the current user change other settings!).
  2. IntelliSense let you believe you have to add a secondary administrator
    When you use the
    SaveButton and use a custom control template for the list / content type.
    SPSite.SelfServiceCreateSite, IntelliSense tells you to provide string values for the secondary site collection administrator. By default my first instinct is to provide it with string.Empty (or perhaps “”). But this doesn’t work. You’ll get an error stating the user can’t be found or something like that. Instead you have to provide the function with null values.
  3. This will only work on POST actions
    SPSite.SelfServiceCreateSite will only allow you to create new site collections on POST actions. When you use the function on a GET action, you’ll get a nice security exception telling you not to do that. This means you can’t easily provide this functionality in an event receiver (they are triggered AFTER the post event). If you still want to use it in an event receiver one way to get this working is to create your own
  4. Not everybody may create site collections
    If you don’t want everybody to create site collections, you can prevent it by simply changing the permissions. By default the Site Permission to allow users to use Self-Service Site Creation is given to the Read role (so for all visitors!)
    090909_2012_selfservice6
  5. Users trying to create the site twice
    The operation to create a site collection might take a few seconds. This time will increase if you automatically want to activate features. An impatient user might want to “speed up” the process by clicking on the submit button again. This might cause the user to see a nice exception stating that the site is already created (he clicked the button twice, so he tries to create a site on the URL twice). To prevent this problem from occurring you might want to provide the user with a progress window. For this you can for example use the SPLongOperation

Download the code

Advertisements
Categories: Development, SharePoint
  1. August 21, 2010 at 14:11

    Indeed its a best option if on wants to create Site collections specific to user without using elevated privildges.

    Good article Peter…

  2. Thumbs
    November 30, 2010 at 10:53

    Hi Peter,
    This is a great post!

    Any idea how you would integrate the PeoplePicker/Editor control to the user selection part?

    Thumbs up!

    • Peter Heibrink
      November 30, 2010 at 12:58

      For this you can use the PeopleEditor control which is shipped with SharePoint.

      On the following page there is a simple example of using this control to get the login name of users: Using the SharePoint People Picker

      You probably want to set the control to not allow multiselect of users and you might want to limit the users which can be chosen. Karine Bosch has made a blog about the settings: PeopleEditor Control

      • Thumbs
        November 30, 2010 at 14:40

        Hi Peter,

        Thanks for the quick response!
        I’ll have a look and keep you posted.

        Kind Regards,
        Thumbs

  3. Thumbs
    January 11, 2011 at 14:05

    Hi Peter,

    A small question regarding a line in your code.
    i’m trying to put your code in an application page but Visual Studio throws an error on the line:

    using (SPSite rootSite = new SPSite(GetAuthorityUrl(SPContext.Current.Web.Url)))

    On the GetAuthorityUrl I get a: The name ‘GetAuthorityUrl’ does not exist in the current context
    I tried to find some info about GetAuthorityUrl but could’t find to much info on it…

    Any ideas?
    Thanks in advance!
    thumbs

    • Peter Heibrink
      January 11, 2011 at 17:46

      Hi Thumbs,

      The method GetAuthorityUrl is one of the methods I created myself. If you download the complete source code you will find the method at line 323 in the file SelfServiceSiteCreationWebPart.cs


      Peter

  4. jeeth
    February 16, 2011 at 11:46

    Hi Peter,

    In my sharepoint portal I’m creating new sites using this method. Code was working fine. When I moved everything to new system, site creation alone sopped working

    Error that I’m getting is System.InvalidOperationException: Feature ‘bc131b21-1a4a-464d-ba2c-dfe4b26031b5’ is not installed in this farm, and can not be added to this scope.

    Also I see these things when enabled diagnostics and checked trace

    Failed to activate site-collection-scoped features for template ‘******#1’ in site collection site name

    Failed to apply template “*********#1” to web at URL

    I have enabled the settings that you mentioned in this article

    Can you helping me in fixing the issue

    Thanks,
    Jeeth

    • Peter Heibrink
      February 16, 2011 at 17:01

      Hi Jeeth,

      I did a quick search in the feature folder in the 12-hive, but I cannot find a feature with that ID (‘bc131b21-1a4a-464d-ba2c-dfe4b26031b5′). Can you check if you are missing a solution and if you can find the feature in your feature folder? Perhaps you need to reinstall the feature. Looking at your comment it seems that the error occurs since the site tempate you are using wants to activate a custom feature which is not installed properly.

      Let me know how it goes!

      Peter

  5. jeeth
    February 21, 2011 at 11:14

    Hi Peter,

    Thanks for the response, this did help me.
    I checked the onet.xml of the sitetemplate and found one custom feature which is required by the site template and installed it and I got it working

    Thanks,
    Jeeth

  6. April 12, 2011 at 16:50

    I’ve been searching in google for some items and occasionally found your peterheibrink.wordpress.com web site.
    Thank you for taking the time to discuss this, it’s a useful info and I love learning more on this. If possible, would you mind updating your blog with more information? It is so helpful for me.

  7. Anonymous
    September 6, 2011 at 07:18

    Hi

    Is it possible to create host named site collections like http://test.content.com with the above method? i dont want managed paths like http://content.com/test…………

    if yes, pls give me the details…

    When i am trying to create with u r solution i am getting the below error…
    {“Another site already exists at http://content. Delete this site before attempting to create a new site with the same URL, choose a new URL, or create a new inclusion at the path you originally specified.”}

  8. June 1, 2012 at 04:20

    Just to let you know your site looks a little bit strange on Firefox on my pc with Linux .

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Ben Prins

What I want to remember about SharePoint

blog.frederique.harmsze.nl

my world of work and user experiences

Bram de Jager - Coder, Speaker, Author

Office 365, SharePoint and Azure

%d bloggers like this: