Programmatically creating Sites and Site Collections from a Custom Web Template

, , , ,

One of the great improvements in SharePoint 2010 are Web Templates. Mirjam van Olst wrote recently a great article about why using light-weight Web Templates is a better approach than using full blown Site Definitions. While using Web Templates for creating sites and Site Collections is pretty straight-forward things get complicated when you need to create the Site Collection programmatically.

The solution

Let’s start with looking at a working code sample that allows you to create a Site Collection using a Web Template:

SPWebApplication webApp = SPWebApplication.Lookup(new Uri("http://win2008"));
using (SPSite site = webApp.Sites.Add("/sites/site1", "SharePoint", null, 1033, null, "administrator", "Administrator", "admin@contoso.com"))
{
    SPWeb rootWeb = site.RootWeb;

    // Get Solutions Gallery
    SPDocumentLibrary solutions = (SPDocumentLibrary)site.GetCatalog(SPListTemplateType.SolutionCatalog);
    // Upload Solution File with the Web Template
    SPFile solutionFile = solutions.RootFolder.Files.Add("test.wsp", File.ReadAllBytes(@"..\..\test.wsp"));
    // Activate Solution
    SPUserSolution solution = site.Solutions.Add(solutionFile.Item.ID);
    // Activate Features
    Guid solutionId = solution.SolutionId;

    // Activate Site Collection Features
    SPFeatureDefinitionCollection siteFeatures = site.FeatureDefinitions;
    var features = from SPFeatureDefinition f
                   in siteFeatures
                   where f.SolutionId.Equals(solutionId) && f.Scope == SPFeatureScope.Site
                   select f;
    foreach (SPFeatureDefinition feature in features)
    {
        site.Features.Add(feature.Id, false, SPFeatureDefinitionScope.Site);
    }

    // Get Web Template
    SPWebTemplateCollection webTemplates = site.RootWeb.GetAvailableWebTemplates(1033);
    SPWebTemplate webTemplate = (from SPWebTemplate t
                                 in webTemplates
                                 where t.Title == "test"
                                 select t).FirstOrDefault();
    if (webTemplate != null)
    {
        site.RootWeb.ApplyWebTemplate(webTemplate.Name);
    }
}

In order to create a new Site Collection you need a reference to the Web Application (1). You can create a new Site Collection by calling the SPSiteCollection.Add method (2). The important part of creating a Site Collection that uses a Web Template is, that you have to create a blank Site Collection at first and apply the template later. Todd discussed this in detail in his post.

After you create an empty Site Collection you can proceed with uploading the WSP file that contains the Web Template. You can do this by retrieving the reference of the Solutions Gallery (7) and adding the file to the Root Folder (9). While adding the file you need to store the reference to the SPFile object. Later on you will be needing the ID of the created List Item in order to activate the Sandboxed Solution.

The next step is to activate the Sandboxed Solution. You can do this by calling the SPUserSolutionCollection.Add method passing the ID of the solution file stored earlier (11). Important difference while activating a Sandboxed Solution programmatically and using the web UI is, that when using code no Features are getting activated. So in order to be able to use your Web Template you need to activate the Site Collection Features from the Sandboxed Solution.

In order to activate the Site Collection Features from the Sandboxed Solution you need the Solution ID (13). Using this ID you can find out which Features are a part of the Sandboxed Solution and should be activated. You can easily retrieve the Features using LINQ (16-20). The things that you have to check for are the Solution ID and Feature’s Scope (19): only Site Collection scoped Features must be activated. Site scoped Features are getting activated automatically by the Web Template itself when applied to the Site. If you activate Site scoped Features you will get error while applying the Web Template to your Site. While activating the Features it’s important to use the Add(Guid, bool, SPFeatureDefinitionScope) overload (23). By setting the third parameter to SPFeatureDefinitionScope.Site you let SharePoint know that the Feature is a part of a Sandboxed Solution. If you use a different overload or pass a different value you will get an exception during the Feature activation process.

The next step is to retrieve the Web Template that you want to apply to your empty Site Collection. You can do this by searching the list of available Web Templates (27) for a Web Template with the name provided while saving the Site as Template (test in this example; 30).

The last step is to apply the Web Template to the Site Collection. While using Web Templates you have to use the SPWeb.ApplyWebTemplate(string) overload (34). Web Templates are represented in the SharePoint API using the SPFeatureWebTemplate class which is internal and cannot be used in your code. By providing the name of the Web Template instead, you let SharePoint find the right Web Template for you. If you try to use the SPWeb.ApplyWebTemplate(SPWebTemplate) overload you will end up with a broken Site.

And that’s it. Using the code above allows you to programmatically create Sites and Site Collections based on Web Templates.

Technorati Tags:


Possibly related posts

61 Responses to “Programmatically creating Sites and Site Collections from a Custom Web Template”

  1. Sharan Raj Says:

    Can you just share me the working example i am getting object reference not set to an instance of an object exception.

    Waiting for your reply

  2. Waldek Mastykarz Says:

    @Sharan: which line is throwing the exception?

  3. Sharan Raj Says:

    using (SPSite site = webApp.Sites.Add("/sites/site1", "SharePoint", null, 1033, null, "administrator", "Administrator", "admin@contoso.com"))

  4. Sharan Raj Says:

    using (SPSite site = webApp.Sites.Add(\"/sites/site1\", \"SharePoint\", null, 1033, null, \"administrator\", \"Administrator\", \"admin@contoso.com\"))

  5. Waldek Mastykarz Says:

    @Sharan: do you have a Web Application with the address http://win2008?

  6. Sharan Raj Says:

    SPSecurity.RunWithElevatedPrivileges(delegate()
    {
    SPWebApplication webApp = SPWebApplication.Lookup(new Uri("http://Swervername:port"));
    using (SPSite site = webApp.Sites.Add("sites/testingsites", "testing for creation of the site", null, 1033, null, "domain\\administrator", "administrator", "test@test.com"))
    {
    SPWeb rootWeb = site.RootWeb;

    // Get Solutions Gallery
    SPDocumentLibrary solutions = (SPDocumentLibrary)site.GetCatalog(SPListTemplateType.SolutionCatalog);
    // Upload Solution File with the Web Template
    SPFile solutionFile = solutions.RootFolder.Files.Add("test.wsp", File.ReadAllBytes(@"..\site template\test.wsp"));
    // Activate Solution
    SPUserSolution solution = site.Solutions.Add(solutionFile.Item.ID);
    // Activate Features
    Guid solutionId = solution.SolutionId;

    // Activate Site Collection Features
    SPFeatureDefinitionCollection siteFeatures = site.FeatureDefinitions;
    var features = from SPFeatureDefinition f
    in siteFeatures
    where f.SolutionId.Equals(solutionId) && f.Scope == SPFeatureScope.Site
    select f;
    foreach (SPFeatureDefinition feature in features)
    {
    site.Features.Add(feature.Id, false, SPFeatureDefinitionScope.Site);
    }

    // Get Web Template
    SPWebTemplateCollection webTemplates = site.RootWeb.GetAvailableWebTemplates(1033);
    SPWebTemplate webTemplate = (from SPWebTemplate t
    in webTemplates
    where t.Title == "test"
    select t).FirstOrDefault();
    if (webTemplate != null)
    {
    site.RootWeb.ApplyWebTemplate(webTemplate.Name);
    }
    }
    });

    This is the same solution wht iam trying to use but no success and i cannot able to trace the error as there is a problem with my ide i.e vs2010 as it is not allowing me to debug the w3p3 process i am planning to change my ide version to 2008 which is far better than this one.
    Please provide me any solution file whcih was already developed so that i can refer it for my solutiion.

  7. Waldek Mastykarz Says:

    @Sharan: this code should work correctly. There is no difference in how VS2010 and VS2008 deal with attaching debugger to a process.

  8. Sharan Raj Says:

    ya what you said was right but it is a problem with my ide what i am using. I have downloaded the evaluation version of vs2010 ultimate may be that is giving the problem for me. If possible can you share the solution that is working.

    One more question
    // Upload Solution File with the Web Template
    SPFile solutionFile = solutions.RootFolder.Files.Add("test.wsp", File.ReadAllBytes(Server.MapPath("../my site template/test.wsp")));

    This my site template is a physical folder in the virtual directory of my site, i have downloaded the site template .wsp package and i have placed that wsp package into the site template folder and i am trying to refer that file
    but with no success.

  9. Waldek Mastykarz Says:

    @Sharan: the evaluation version of Visual Studio 2010 shouldn't be a problem: it has the full functionality but only for a limited time.

  10. Sharan Raj Says:

    SPSecurity.RunWithElevatedPrivileges(delegate()
    {
    using (SPSite siteCollectionOuter = new SPSite("http://ServerName:PortNumber/"))
    {
    SPWebApplication webApp = siteCollectionOuter.WebApplication;
    SPSiteCollection siteCollection = webApp.Sites;
    SPSite site = siteCollection.Add("sites/testsite", "Testing", null, 1033, "STS#1", "Domain\\User", "User", "mymail@domain.com");

    SPWeb rootWeb = site.RootWeb;

    // Get Solutions Gallery
    SPDocumentLibrary solutions = (SPDocumentLibrary)site.GetCatalog(SPListTemplateType.SolutionCatalog);
    // Upload Solution File with the Web Template
    SPFile solutionFile = solutions.RootFolder.Files.Add("test.wsp", File.ReadAllBytes(Server.MapPath("../mysitetemplate/test.wsp")));
    // Activate Solution
    SPUserSolution solution = site.Solutions.Add(solutionFile.Item.ID);
    // Activate Features
    Guid solutionId = solution.SolutionId;

    lblError.Text = "Success";
    }
    });

    with this solution i am able to create the site, but the test.wsp file is not getting uploaded to the root site solution library. What was the mistake i am doing in this code snippet.

    In the above code mysitetemplate is a folder in my virtual directory where in i have placed the test.wsp file physically.

  11. Waldek Mastykarz Says:

    @Sharan: Have you tried to attach debugger and step through the code to get some more information about what's exactly failing?

  12. Sharan Raj Says:

    Hai ,

    I tried to debug the above code the site got created with STS#1 code and the test.wsp file not getting uploed into the Solution library of the root site collection. It didnot give any error the program run successfully. I am not getting why it is not getting uploaded to the solution library.

  13. Waldek Mastykarz Says:

    @Sharan: how about trying to put there a full path just to be sure that everything works correctly?

  14. Hans Says:

    How can I create a Site (not Site Collection) from a wsp file I created by saving a site as template?

  15. Waldek Mastykarz Says:

    @Hans: I guess you could try creating a Site without applying the template and then using the code starting from line #27 to retrieve and apply the template.

  16. TR Says:

    Hi,

    I am not sure that I fully understand your code (clearly my fault).

    Can you confirm that this is the method:

    1) create the site collection without referencing a site template
    2) adding the .wsp (from file system) to the newly created site colls solution gallery
    3) activate solution
    4) (some feature handling ?)
    5) getting a ref. to the site template (using template title)
    6) applying the template to the newly created site coll

    Your comments would be much appreciated.

  17. Khan Says:

    Hi,

    It is a nice post. I have tried the above code. I suceeded to create site collection, to upload WSP (template) file in root solution gallery and also it activated successfully. I am not succeeded to get uploaded template. When i debug the following code(i.e.webTemplate variable )contain null value. When i checked the avilable template names return in webtemplatecolletion it doesn't contain my uploaded template display name.

    SPWebTemplate webTemplate = (from SPWebTemplate t in webTemplates where t.Title == "TeamSiteTemp"
    select t).FirstOrDefault();

    I really appretiate your urgent help in this regard as i already spent lot of time to make it workable. Thanks

  18. Khan Says:

    Thanks for nice post. I succeded to create site collection, to upload custom template file in solution gallery and able to activate it. I have no error in code it deploy successfully but my custom activated template not attach with newly created site collection. When i debug i figured out that the code in your post on line 28 contain null value and not able to find custom uploaded template. I also check that the values return in SPWebTemplateCollection doesn't contain name of custom template. I am struggling alot to figure it out but ot suceeded. I really appretaite your urgent help in this regards. Thanks

  19. Waldek Mastykarz Says:

    @TR: these are exactly the steps. Lines #15-24 are about activating the Site Collection Feature that makes the Web Template available in the Site Collection.

  20. Waldek Mastykarz Says:

    @Khan: in line 9 you are uploading the WSP file that contains your Web Template. Can you confirm that the file has been correctly uploaded to the Site Collection?

  21. Khan Says:

    Hi,

    Thanks for your quick response. I figured out the problem, actually i have used the earlier created site template file (.WSP) and some how i earlier renamed this file so i was referring with current name and originally it stored with earlier name in site templates collection. So it solved. One question what is the best place/path where we physically store these site template files(.wsp) in production server environment. Thanks.

  22. Waldek Mastykarz Says:

    @Khan: great to hear everything is working for you :)

  23. Matt Jensen Says:

    Hi,

    I used your example above and on my testing machine (single server, win 7 64-bit OS) it works fine, however when I attempted to move this to production I keep getting access denied.

    I have added all the permissions I can think of to the app pool, but no matter what I do I get access denied.

    If there is anything you can think of that would help me solve this problem I would greatly appreciate it.

    Thanks,
    Matt

  24. Waldek Mastykarz Says:

    @Matt: how do you run this code? Are you using a custom Console Application or something else?

  25. Matt Jensen Says:

    I am running the code in a webpart. I want end users to be able to create a site collection, but when they do I want it to use a custom template. So I thought I would create a web part that would allow them to do this.

    The web part takes in a site name and url string, and then when they click the button trys to create the site.

    Because it is a web part running under the end users permissions I change the code a little to use the spsecurity.runwithelevatedpermissions. Which from what I understand makes the code run under the app pool. However, no matter what I have given the app pool permission to so far it always comes back access denied.

    Matt

  26. Waldek Mastykarz Says:

    @Matt: could you post some of the code here so that I can verify that it's running under the AppPool credentials indeed?

  27. Matt Jensen Says:

    The button event is:

    Protected Sub btnCreate_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnCreate.Click

    Try

    \\\'Hide the error message
    lblError.Visible = False
    lblError.Text = String.Empty

    \\\'Check to make sure a site name and url have been entered
    If (Not String.IsNullOrEmpty(txtSiteName.Text)) AndAlso (Not String.IsNullOrEmpty(txtSiteURL.Text)) Then

    Me.User = SPContext.Current.Web.CurrentUser

    \\\'Create the new site collection
    Dim elevatedCode As New SPSecurity.CodeToRunElevated(AddressOf CreateSite)
    SPSecurity.RunWithElevatedPrivileges(elevatedCode)

    Else

    \\\'No site name or url was provided so display the error message
    lblError.Text = \\"You must provide a site name and URL\\"
    lblError.Visible = True

    End If

    Catch ex As ArgumentException

    \\\'The site url is already in use so display the error message
    lblError.Text = \\"Site URL is already in use. Please provide a different URL.\\"
    lblError.Visible = True

    Catch ex As SPException

    \\\'Check to see if the error returned was invalid characters in the url
    If (ex.ErrorCode = -2146232832) Then

    \\\'Invalid characters were used in the URL so display the error message
    lblError.Text = \\"Site URL contains invalid characters. Please provide a different URL.\\"
    lblError.Visible = True

    Else

    LogExceptionToLogger(ex, \\"UNABLE_TO_CREATE_SITE_COLLECTION\\", PerformanceLogMessageType.Error)

    End If

    Catch ex As Exception

    LogExceptionToLogger(ex, \\"UNABLE_TO_CREATE_SITE_COLLECTION\\", PerformanceLogMessageType.Error)

    End Try

    End Sub \\\' End btnCreate_Click

    The create site sub is:

    Private Sub CreateSite()

    \\\'Hide the error message
    Me.lblError.Visible = False
    Me.lblError.Text = String.Empty

    \\\'Check to make sure a web app url has been provided
    If Not (String.IsNullOrEmpty(Me.WebAppURL)) Then

    \\\'Check to make sure a document library name was provided
    If Not (String.IsNullOrEmpty(Me.LibraryName)) Then

    \\\'Check to make sure a template name was provided
    If Not (String.IsNullOrEmpty(Me.TemplateName)) Then

    \\\'Get the wsp file
    Dim library As SPDocumentLibrary = CType(SPContext.Current.Web.Lists(Me.LibraryName), SPDocumentLibrary)
    Dim file As Stream = Nothing

    Try

    Dim tempName = Me.TemplateName & \\".wsp\\"

    For Each item As SPListItem In library.Items

    If (item.Name = tempName) Then

    file = item.File.OpenBinaryStream

    End If

    Next

    Catch ex As Exception

    LogExceptionToLogger(ex, \\"UNABLE_TO_CREATE_SITE_COLLECTION\\", PerformanceLogMessageType.Error)

    End Try

    \\\'Check to make sure we found the file
    If (file IsNot Nothing) Then

    \\\'Get a reference to the web application to create the site under
    Dim webApp As SPWebApplication = SPWebApplication.Lookup(New Uri(Me.WebAppURL))

    \\\'Check to make sure we got a reference to the web app
    If (webApp IsNot Nothing) Then

    Try

    \\\'Create the new site collection
    Using Site As SPSite = webApp.Sites.Add(Me.WebAppURL & \\"/sites/\\" & txtSiteURL.Text, txtSiteName.Text, String.Empty, _
    1033, Nothing, Me.User.LoginName, Me.User.Name, _
    Me.User.Email)

    \\\'Get a reference to the solution gallery of the new site collection
    Dim solutions As SPDocumentLibrary = CType(Site.GetCatalog(SPListTemplateType.SolutionCatalog), SPDocumentLibrary)

    \\\'Upload the solution to the solution gallery
    Dim solutionFile As SPFile = solutions.RootFolder.Files.Add(Me.TemplateName & \\".wsp\\", file)

    \\\'Activate Solution
    Dim solution As SPUserSolution = Site.Solutions.Add(solutionFile.Item.ID)

    \\\'Get Solution ID
    Dim solutionID As Guid = solution.SolutionId

    \\\'Activate Site Collection Features
    Dim siteFeatures As SPFeatureDefinitionCollection = Site.FeatureDefinitions

    Dim features = From feature As SPFeatureDefinition In siteFeatures _
    Where feature.SolutionId.Equals(solutionID) And feature.Scope = SPFeatureScope.Site _
    Select feature

    For Each item As SPFeatureDefinition In features

    Site.Features.Add(item.Id, False, SPFeatureDefinitionScope.Site)

    Next

    \\\'Get Web Template to use for the new site collection
    Dim webTemplates As SPWebTemplateCollection = Site.RootWeb.GetAvailableWebTemplates(1033)

    Dim webTemplate As SPWebTemplate = (From templates As SPWebTemplate In webTemplates _
    Where templates.Title = Me.TemplateName _
    Select templates).FirstOrDefault

    \\\'Check to make sure we have the template
    If (webTemplate IsNot Nothing) Then

    \\\'apply the template
    Site.RootWeb.ApplyWebTemplate(webTemplate.Name)

    Else

    Me.lblError.Text = \\"We have encountered an error while attempting to create the new site.\\" & _
    \\"This error has been logged. If you encounter this error again please contact the Service Desk at 297-2727\\"

    Me.lblError.Visible = True

    Throw New Exception(\\"Unable to locate the web template for the new site collection\\")

    End If

    End Using

    Catch ex As Exception

    LogExceptionToLogger(ex, \\"UNABLE_TO_CREATE_SITE_COLLECTION\\", PerformanceLogMessageType.Error)

    End Try

    \\\'Create the URL string to the new site collection
    Dim newURL As String = Me.WebAppURL & \\"/sites/\\" & txtSiteURL.Text

    \\\'Clear the information the user enterd
    Me.txtSiteName.Text = String.Empty
    Me.txtSiteURL.Text = String.Empty

    Try

    \\\'Send the user to their new site
    Response.Redirect(newURL)

    Catch ex As Threading.ThreadAbortException

    System.Threading.Thread.ResetAbort()

    End Try

    There is alot of else\\\'s at the bottom here, but left them out to keep this as short as possible. There are some properties on the web part for the web app url and the template name and folder.

    Matt

  28. Matt Jensen Says:

    Wow! Sorry about the several posts. It told me invalid security code so I tried and again and it tripled my post!

  29. Waldek Mastykarz Says:

    @Matt: Have you tried attaching debugger to the code to find out which line of code exactly is causing the error?

  30. Matt Says:

    Yes and it is the line where it creates the new site. However I went another way, I am just using the web service to create the new site collection and then doing the rest like above. It worked for the most part, but now i am getting some errors when applying the custom template. It Is usually errors about a feature not being activated. I still working on it

  31. Robert Says:

    Hey Waldek. you have a great post here, but I've been running into a wall repeatedly, and I was really hoping you could help me out.

    The line:
    SPSite site = webApp.Sites.Add(@"……………) always results in an unauthorizedAccessException 0×80070005 error.

    I've tried running the code with SPSecurity.escalatedprivledges, under various administration accounts, etc, to no success. I've even tried the code Sharan Raj posted in these comments, but I always get the same error on the siteCollection.Add line. If I place a try catch around the line, the page is auto-redirected to the unauthorized login page.

    Do you have any suggestions?
    Thank you.
    Robert

  32. Waldek Mastykarz Says:

    @Robert: If the account has sufficient privileges you should be able to do this. Have you tried doing that using the same account as when creating a Site Collection through Central Administration?

  33. Olo Says:

    Creating site collections also gave me UnauthorizedAccessException. This happens everytime if I open any collection in any web (eg. try to get SPItem or SPList).
    So, DON'T TOUCH LISTS, and first create SPSite.
    I know it's stupid, but I bet "it's a feature not a bug".

  34. Divyesh Kotadia Says:

    Hi Waldek,

    Can you please give me equivalent Power Shell script for code you provided. I am currently automating create site collection stuff using custom site template.

    Thanks,
    Divyesh

  35. Moss Junkie Says:

    Excellent post. Saved me tons of time on a recent engagement. I have created an equivalent powershell script for the above code. http://mossjunkie.blogspot.com/2011/01/creating-site-collections-from-custom.html

  36. Amal Says:

    Waldek,

    It is a nice post. It was really helpful.
    I was able to create site collection using the custom site template but when i tried creating the site collection using the custom publishing site template (Branding), I am getting publishing site dependency error.
    Do you have any idea regarding the same? I have activated the publishing infrastructure feature of the site collection and publishing feature of the subsite.

    Best Regards,
    Amal

  37. Waldek Mastykarz Says:

    @Amal: You should be able to get this to work. I'd suggest you start off the Publishing Site Definition which should provide you with all the necessary Features that you need to use the Publishing capabilities of SharePoint.

  38. Amal Says:

    Waldek,

    Thanks for the reply.

    I tried with the Publishing site tempate (publishing portal) but there too i need to activate the Sharepoint server publishing infrastructure feature at the site collection level.

    AM I missing anything here?

    Do you know programmatically how to activate the Sharepoint server publishing infrastructure feature at the site collection level?

    I tried the below but it is giving error as "Feature not installed in the farm".

    string pubFeatureID = "F6924D36-2FA8-4f0b-B16D-06B7250180FA";
    Guid PublishingInfraFeatureID = new Guid(pubFeatureID);
    site.Features.Add(PublishingInfraFeatureID, true, SPFeatureDefinitionScope.Site);

    Best Regards,
    Amal

  39. Waldek Mastykarz Says:

    @Amal: I've just used the following code snippet and it worked okay:

    using (SPSite site = new SPSite("http://win2008/"))
    {
    site.Features.Add(new Guid("f6924d36-2fa8-4f0b-b16d-06b7250180fa"));
    }

    How are you trying to run your code? If you're creating a custom Web Template you might as well use the declarative approach using XML in onet.xml instead of custom code.

  40. Amal Says:

    Below is the code snippet used…

    SPWebApplication webApp = SPWebApplication.Lookup(new Uri("http://win2008"));

    using (SPSite site = webApp.Sites.Add("/sites/site1", "SharePoint", null, 1033, null, "administrator", "Administrator", "admin@contoso.com")) { SPWeb rootWeb = site.RootWeb;

    // Get Solutions Gallery SPDocumentLibrary solutions = (SPDocumentLibrary)site.GetCatalog(SPListTemplateType.SolutionCatalog);

    // Upload Solution File with the Web Template SPFile solutionFile = solutions.RootFolder.Files.Add("test.wsp", File.ReadAllBytes(@"..\..\test.wsp"));

    // Activate Solution SPUserSolution solution = site.Solutions.Add(solutionFile.Item.ID);

    // Activate Features Guid solutionId = solution.SolutionId;

    // Activate Site Collection Features SPFeatureDefinitionCollection siteFeatures = site.FeatureDefinitions;

    //code for activating the sharepoint server publishing infrastructure – I am getting error saying that feature not installed in the farm
    string pubFeatureID = "F6924D36-2FA8-4f0b-B16D-06B7250180FA";
    Guid PublishingInfraFeatureID = new Guid(pubFeatureID);
    site.Features.Add(PublishingInfraFeatureID, true, SPFeatureDefinitionScope.Site);

    var features = from SPFeatureDefinition f in siteFeatures where f.SolutionId.Equals(solutionId) && f.Scope == SPFeatureScope.Site select f; foreach (SPFeatureDefinition feature in features) { site.Features.Add(feature.Id, false, SPFeatureDefinitionScope.Site); }

    // Get Web Template SPWebTemplateCollection webTemplates = site.RootWeb.GetAvailableWebTemplates(1033); SPWebTemplate webTemplate = (from SPWebTemplate t in webTemplates where t.Title == "test" select t).FirstOrDefault(); if (webTemplate != null) { site.RootWeb.ApplyWebTemplate(webTemplate.Name); } }

  41. Amal Says:

    Got the solution.

    I was activating the GUID of the SharePoint Server Publishing Infrastructure at the wrong place.

    Thanks for the reply

  42. Waldek Mastykarz Says:

    @Amal: sure, no problem. Does it mean you've got it all working?

  43. Amal Says:

    Waldek,

    I got the solution to activate the SharePoint Server Publishing Feature at the site collection level Code.

    Still things are not complete yet.
    When i navigate to the newly created site collection, it shows 404 error.

    When i navigate to the site collection features, SharePoint server Publishing feature is activated.

    Branding is also activated properly.

    I am investigating the issue.

    My Custom Site template (team site) had Survey, Discussion and Blog.

    In the newly created site collection, I am getting survey and discussion but blog is not there.

  44. Amal Says:

    Waldek,

    Can a custom site template having sites like blog etc can be used for site collection creation?

    Best Regards,
    Amal

  45. Waldek Mastykarz Says:

    @Amal: That depends on the Site Definition. To be sure you would have to check if it can be used for Subwebs only or not.

  46. Waldek Mastykarz Says:

    @Amal: Have you checked if you're getting any errors during the process of creating/configuring the Site Collection?

  47. Amal Says:

    Waldek,

    The Custom Site template which i am using contains the following

    1) Site Type – Team Site
    2) Custom Branding feature
    2.a) Custom theme/style/css
    2.b) Custom Page Layout
    3) OOB Survey List
    4) OOB Discussion List
    5) Blog Subsite

    The Site collection features activated are
    1) Advanced Web Analytics
    2) Custom branding feature
    3) Disposition workflow
    4) Librarty and folder retention
    5) SharePoint Server publishing infrasture
    6) SharePoint Server Enterprise site collection feature
    7) SharePoint Server STandard site collection feature
    8) Three state workflow
    9) Workflows

    Site Features are
    1) SHarepoint server Publishing
    2) Team collaboration list
    3) Offline sync for list

    When i am using the above custom site template, I am able to create the site collection but following things are not getting configured/created

    1) Site/Page is not getting published
    2) Custom Page layout is not getting applied
    3) Blog subsite is not getting created

    AM i missing anything?
    Do i need to enable any site collection or site feature?

  48. Waldek Mastykarz Says:

    @Amal: How are you doing the last three steps that don't work: declaratively using XML or imperatively in the Feature Receiver of a Feature activated in your Web Template?

  49. Amal Says:

    I am creating the site collection using the custom site template (custom Branding, survey list, discussion list and blog subsite) through the execute method of the custom workflow action.

    The custom worflow action is used by the declaration workflow which is associated to the content type.

    I am using the Site collection administrator for creating the site collection.

    As discussed earlier, the custom site template was built using the team site type.

  50. Amal Says:

    Process that i used for creating the custom site template:

    1) Created the Site collection from the central administration manually and selected the site type as "team site"
    2) Added Custom branding to the site collection (scope set to site collection)
    3) Added the OOB survey list
    4) Added the OOB Discussion List

    Saved the site template forcefully using the url _layouts/savetmpl.aspx

    The saved WSP (custom site template) was used in the code to create the site collection.

  51. Waldek Mastykarz Says:

    @Amal: Publishing functionality is not supported in saving sites as templates so that might explain why it isn't working correctly. Instead of saving the site as template, you should create a Web Template that would include the Publishing Features.

  52. Amal Says:

    Waldek,

    I have activated SharePoint Server publishing Infrasture – scoped to site collection through code.

    The only part to achieve in my scenario is to carry the subsites along with the custom site templates other than that I am able to achieve all.

    Do you know how to create site collection using custom site template having subsites? Do i need to enable any setting or site collection feature?

  53. Amal Says:

    Waldek,
    One of my colleague told me that there is a setting to made before saving the site containing sub-sites. I am looking into it.

    Are you aware of such setting? Will inform you if i get the setting for saving the subsites.

    Best Regards,
    Amal

  54. Amal Says:

    Waldek,

    I was not able to figure out the setting for the saving site template using sub sites.
    Mostly would be taking the approach of creating the site definition having subsites configure in it and then use for the site collection provisioning.

  55. Naren Says:

    Hi, I have created a site collection in SP 2010.. But when tries to print that root url.. it shows the following error:: Verify that you have typed the URL correctly. If the URL should be serving existing content, the system administrator may need to add a new request URL mapping to the intended application. my code is using(SPSite spobj = new SPSite("mysiteurl")) { print(spobj.RootWeb.Title) }

  56. Sandy Says:

    Check your URL. You probably need to use https://"yourSiteName". I recently ran into this issue myself!

  57. Colin Dekker Says:

    Waldek, this code will not work running from say inside a webpart, not even using RunWithElevatedPriviliges. YOu need to be Farm admin (i.e. access to the configdb) to add a site collection it seems. And SP1 added an extra hurdle by requiring the RemoteAdministratorAccessDenied of the ContentService SPWebService.
    At least, i have not been able to create a site collection using SPWebApplication.Sites.Add from anything that isn't running with farm admin level credentials

  58. Waldek Mastykarz Says:

    That's interesting, Colin. Thanks for sharing.

  59. Colin Dekker Says:

    SLight error: RemoteAdministratorAccessDenied needs to be false if you want to make changes to the webapp that require a call to webapp.Update() (ie adding an OfficialFileHost)

  60. Robert Babb Says:

    Waldek, Thank you for the post. Like others that have posted above, your concise example has saved me hours of banging my head against the wall. Thank you!

  61. Waldek Mastykarz Says:

    @Robert: Great to hear I could help :)

Leave a Reply

Security Code:

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS
Copyright © 2007 - 2012 Waldek Mastykarz

Creative Commons License