private string CreateSubsite(SSConfig selectedConfig)
        {
            string webUrl = selectedConfig.BasePath + txtUrl.Text;

            //create subsite
            var parentSite = new Uri(selectedConfig.BasePath);  //static for my tenant
            var token      = TokenHelper.GetAppOnlyAccessToken(SHAREPOINT_PID, parentSite.Authority, null).AccessToken;

            using (var clientContext = TokenHelper.GetClientContextWithAccessToken(parentSite.ToString(), token))
            {
                var properties = new WebCreationInformation()
                {
                    Url         = txtUrl.Text,
                    Title       = txtTitle.Text,
                    Description = txtDescription.Text,
                    WebTemplate = selectedConfig.SiteTemplate,
                    UseSamePermissionsAsParentSite = false
                };

                //create and load the new web
                Web newWeb = clientContext.Web.Webs.Add(properties);
                clientContext.Load(newWeb, w => w.Title);
                clientContext.ExecuteQuery();

                //TODO: set additional owners

                //apply the masterpage to the site (if applicable)
                if (!String.IsNullOrEmpty(selectedConfig.MasterUrl))
                {
                    newWeb.MasterUrl       = selectedConfig.MasterUrl;
                    newWeb.CustomMasterUrl = selectedConfig.MasterUrl;
                }

                /**************************************************************************************/
                /*   Placeholder area for updating additional settings and features on the new site   */
                /**************************************************************************************/

                //update the web with the new settings
                newWeb.Update();
                clientContext.ExecuteQuery();
            }

            return(webUrl);
        }
        protected void btnCreate_Click(object sender, EventArgs e)
        {
            //get the selected config
            SSConfig selectedConfig = configList.FirstOrDefault(i => i.Title.Equals(hdnSelectedTemplate.Value));

            if (selectedConfig != null)
            {
                string webUrl = "";
                if (selectedConfig.SiteType.Equals("Site Collection", StringComparison.CurrentCultureIgnoreCase))
                {
                    webUrl = CreateSiteCollection(selectedConfig);
                }
                else
                {
                    webUrl = CreateSubsite(selectedConfig);
                }

                //redirect to new site
                ClientScript.RegisterStartupScript(typeof(Default), "RedirectToSite", "navigateParent('" + webUrl + "');", true);
            }
        }
        private string CreateSiteCollection(SSConfig selectedConfig)
        {
            string webUrl = "";

            //create site collection using the Tenant object
            var tenantAdminUri = new Uri(TENANT_ADMIN_URL);  //static for my tenant
            var token          = TokenHelper.GetAppOnlyAccessToken(SHAREPOINT_PID, tenantAdminUri.Authority, null).AccessToken;

            using (var clientContext = TokenHelper.GetClientContextWithAccessToken(tenantAdminUri.ToString(), token))
            {
                var tenant = new Tenant(clientContext);
                webUrl = String.Format("{0}{1}", selectedConfig.BasePath, txtUrl.Text);
                var properties = new SiteCreationProperties()
                {
                    Url                  = webUrl,
                    Owner                = "*****@*****.**",
                    Title                = txtTitle.Text,
                    Template             = selectedConfig.SiteTemplate,
                    StorageMaximumLevel  = Convert.ToInt32(selectedConfig.StorageMaximumLevel),
                    UserCodeMaximumLevel = Convert.ToDouble(selectedConfig.UserCodeMaximumLevel)
                };
                SpoOperation op = tenant.CreateSite(properties);
                clientContext.Load(tenant);
                clientContext.Load(op, i => i.IsComplete);
                clientContext.ExecuteQuery();

                //check if site creation operation is complete
                while (!op.IsComplete)
                {
                    //wait 30seconds and try again
                    System.Threading.Thread.Sleep(30000);
                    op.RefreshLoad();
                    clientContext.ExecuteQuery();
                }
            }

            //get the newly created site collection
            var siteUri = new Uri(webUrl);  //static for my tenant

            token = TokenHelper.GetAppOnlyAccessToken(SHAREPOINT_PID, siteUri.Authority, null).AccessToken;
            using (var clientContext = TokenHelper.GetClientContextWithAccessToken(siteUri.ToString(), token))
            {
                var newWeb = clientContext.Web;
                clientContext.Load(newWeb);
                clientContext.ExecuteQuery();

                //update description
                newWeb.Description = txtDescription.Text;

                //TODO: set additional site collection administrators

                //apply the masterpage to the site (if applicable)
                if (!String.IsNullOrEmpty(selectedConfig.MasterUrl))
                {
                    //get the the masterpage bytes from it's existing location
                    byte[] masterBytes  = GetMasterPageFile(selectedConfig.MasterUrl);
                    string newMasterUrl = String.Format("{0}{1}/_catalogs/masterpage/ssp.master", selectedConfig.BasePath, txtUrl.Text);

                    //upload to masterpage gallery of new web and set
                    List list = newWeb.Lists.GetByTitle("Master Page Gallery");
                    clientContext.Load(list, i => i.RootFolder);
                    clientContext.ExecuteQuery();
                    FileCreationInformation fileInfo = new FileCreationInformation();
                    fileInfo.Content = masterBytes;
                    fileInfo.Url     = newMasterUrl;
                    Microsoft.SharePoint.Client.File masterPage = list.RootFolder.Files.Add(fileInfo);
                    string relativeMasterUrl = newMasterUrl.Substring(8);
                    relativeMasterUrl = relativeMasterUrl.Substring(relativeMasterUrl.IndexOf("/"));

                    //we can finally set the masterurls on the newWeb
                    newWeb.MasterUrl       = relativeMasterUrl;
                    newWeb.CustomMasterUrl = relativeMasterUrl;
                }


                /**************************************************************************************/
                /*   Placeholder area for updating additional settings and features on the new site   */
                /**************************************************************************************/

                //update the web with the new settings
                newWeb.Update();
                clientContext.ExecuteQuery();
            }

            return(webUrl);
        }