Create a new site programmatically and select parent site? (SharePoint)

16,215

Solution 1

You should open the SPWeb selected in the dropdown. Use the web id's as the dropdown values, get the context spsite, then use SPSite.OpenWeb(GUID) to open the web you want to be the parent. Add the new Web to that Web's Webs:

private void getSites()
{
   SPSite oSiteCollection = SPContext.Current.Site;
   SPWebCollection collWebsite = oSiteCollection.AllWebs;
      for (int i = 0; i < collWebsite.Count; i++)
   {
       ddlParentSite.Items.Add(new ListItem(collWebsite[i].Title, collWebsite[i].Id));
   }

   // oSiteCollection.Dispose(); // NEVER DISPOSE THE SPContext.Current.Site or Web
}

using( var site = SPContext.GetContext(HttpContext.Current).Site)
{
  using(var parentWeb = site.OpenWeb(new Guid(DDLVALUE))
  {
    newWeb = parentWeb.Webs.Add(newSiteUrl, newSiteName, null, (uint)1033, siteTemplate, true, false);
    try
    {
      newWeb.Update();
    }
  }
}

Solution 2

using( var site = SPContext.GetContext(HttpContext.Current).Site)
{
}

might be causing the issue as you are disposing the site object that you obtained from SPContext.

ANd Micorosoft Says that Do not dispose the contextual webs.

Hope that might help you

Share:
16,215
peter
Author by

peter

Updated on June 14, 2022

Comments

  • peter
    peter almost 2 years

    I am using the following code to create a new site:

    newWeb = SPContext.GetContext(HttpContext.Current).Web.Webs.Add(newSiteUrl, newSiteName, null, (uint)1033, siteTemplate, true, false);
    
                    try
                    {
                        newWeb.Update();
                    }
    

    NewSiteUrl and newSiteName are values from two textboxes and on whichever site I use this code (in a web part) the new site will be a subsite to this site.

    I would now like to be able to select a parent site so that the new site can sit anywhere in the site collection, not just as a subsite to the site where I use the web part.

    I created the following function to get all the sites in the site collection and populate a drop down with the name and url for every site

    private void getSites()
    {
        SPSite oSiteCollection = SPContext.Current.Site;
        SPWebCollection collWebsite = oSiteCollection.AllWebs;
    
        for (int i = 0; i < collWebsite.Count; i++)
        {
            ddlParentSite.Items.Add(new ListItem(collWebsite[i].Title, collWebsite[i].Url));
        }
        oSiteCollection.Dispose();
    }
    

    If the user selects a site in the dropdown, is it possible to use that URL in newSiteUrl so decide where the new site should be? I don't get it to work really and the new site still becomes a subsite to the current one. I guess it has to do with HttpContext.Current? Any ideas on how I should do it instead?

    It's the first time I write custom web parts and the sharepoint object model is a bit overwhelming at the moment.

    Thanks in advance.

    Edit: with updated code gives error: Trying to use an SPWeb object that has been closed or disposed and is no longer valid.

    if (!siteExists(newSiteName) && newSiteName.Length > 0)
                {
                    using (var parent = SPContext.GetContext(HttpContext.Current).Site)
                    { 
                        using(var parentWeb = parent.OpenWeb(new Guid(parentSite)))
                        {
                        newWeb = parentWeb.Webs.Add(newSiteUrl, newSiteName, null, (uint)1033, siteTemplate, true, false);
    
                    try
                    {
                        newWeb.Update();
                    }
    
                    catch
                    {
                        lblErrorCreateSite.Text = "An error occured when trying to create a new site, please try again.";
                    }
                    finally
                    {
    
                        txtSiteName.Text = "";
    
                        // Show link to new site
                        lblNewSite.Text = "A new site was successfully created at ";
                        hplNewSite.Visible = true;
                        hplNewSite.NavigateUrl = siteURL() + newSiteName;
                        hplNewSite.Text = newSiteName;
    
                        // Dispose to reload the SharePoint content database
                        newWeb.Dispose();
    
                    }
    
                    // Set permissions
                    try
                    {
                        string site = siteURL();
                        SPSite spSite = new SPSite(site + newSiteName);
                        SPWeb web = spSite.OpenWeb();
    
                        // Assign Full Access role to the selected groups
                        string fullAccessGroup = null;
                        string fullAccessRole = null;
                        foreach (ListItem item in lbFullAccess.Items)
                        {
                            fullAccessGroup = item.Value;
                            fullAccessRole = "Full Control";
                            SPRoleAssignment roleAssignment = new SPRoleAssignment(web.SiteGroups[fullAccessGroup]);
                            SPRoleDefinitionBindingCollection roleDefinition = roleAssignment.RoleDefinitionBindings;
    
                            roleDefinition.Add(web.RoleDefinitions[fullAccessRole]);
                            web.RoleAssignments.Add(roleAssignment);
                            web.Properties[fullAccessGroup] = fullAccessRole;
                            web.Properties.Update();
                        }
    
                        // Assign Contributor role to the selected groups
                        string contributeGroup = null;
                        string contributeRole = null;
                        foreach (ListItem item in lbContributor.Items)
                        {
                            contributeGroup = item.Value.ToString();
                            contributeRole = "Contribute";
    
                            SPRoleAssignment roleAssignment = new SPRoleAssignment(web.SiteGroups[contributeGroup]);
                            SPRoleDefinitionBindingCollection roleDefinition = roleAssignment.RoleDefinitionBindings;
    
                            roleDefinition.Add(web.RoleDefinitions[contributeRole]);
                            web.RoleAssignments.Add(roleAssignment);
                            web.Properties[contributeGroup] = contributeRole;
                            web.Properties.Update();
                        }
    
                        // Assign Reader role to the selected groups
                        string readerGroup = null;
                        string readerRole = null;
                        foreach (ListItem item in lbReadOnly.Items)
                        {
                            readerGroup = item.Value.ToString();
                            readerRole = "Read";
    
                            SPRoleAssignment roleAssignment = new SPRoleAssignment(web.SiteGroups[readerGroup]);
                            SPRoleDefinitionBindingCollection roleDefinition = roleAssignment.RoleDefinitionBindings;
    
                            roleDefinition.Add(web.RoleDefinitions[readerRole]);
                            web.RoleAssignments.Add(roleAssignment);
                            web.Properties[readerGroup] = readerRole;
                            web.Properties.Update();
                        }
    
                    }
                    catch
                    {
                        lblErrorSetPermissions.Text = "Error trying to set permissions for this site, please try again.";
                    }
                    finally
                    {
    
                    }
    
                }
                    }
                }
                else
                {
                    if (siteExists(newSiteName))
                    {
                        lblErrorCreateSite.Text = "A site with that name already exists. Please select another name.<br/>";
                    }
    
                    if (newSiteName.Length == 0)
                    {
                        lblErrorCreateSite.Text = "A Site Name is required.<br/>";
                    }
    
                    hplNewSite.Visible = false;
                }
    

    Edit2: So I use

    SPSite currentContext = SPContext.GetContext(HttpContext.Current).Site;
    SPWeb parentID = currentContext.OpenWeb(new Guid(parentSiteValue));
    
    newWeb = parentID.Webs.Add(newSiteUrl, newSiteName, null, (uint)1033, siteTemplate, true, false);
    

    But how can I easiest get the url for the newly created site (to display correct url in the link I create and to use when I set permissions)?