Beispiel #1
0
        public static ManageSiteResult ValidateSite(IisSite site, IisSite originalSite)
        {
            var certificates = SiteManager.GetCertificates();

            var result = new ManageSiteResult();

            if (!site.Bindings.Any())
            {
                result.Errors.Add("Minimum one binding is required.");
            }

            if (string.IsNullOrWhiteSpace(site.Name))
                result.Errors.Add("Name is required.");

            IisSite existingSite = SiteManager.GetSiteByName(site.Name);
            if (originalSite == null)
            {
                originalSite = new IisSite() { IisId = 0};
            }

            if (site.Name != null && existingSite != null && site.Name.ToLower() == existingSite.Name.ToLower() && existingSite.IisId != originalSite.IisId)
                result.Errors.Add("There's already a site with this name.");

            if (string.IsNullOrWhiteSpace(site.SitePath))
                result.Errors.Add("Site path is required.");
            else
            {
                if (!FileSystemHelper.IsPathValid(site.SitePath))
                {
                    result.Errors.Add("Path cannot contain the following characters: ?, ;, :, @, &, =, +, $, ,, |, \", <, >, *.");
                }
                else
                {
                    if (!FileSystemHelper.DirectoryExists(site.SitePath))
                    {
                        FileSystemHelper.CreateDirectory(site.SitePath);
                    }
                }

                if (!FileSystemHelper.IsPathValid(site.LogFileDirectory))
                {
                    result.Errors.Add("Log File Directory cannot contain the following characters: ?, ;, :, @, &, =, +, $, ,, |, \", <, >, *.");
                }
                else
                {
                    if (!FileSystemHelper.DirectoryExists(site.LogFileDirectory))
                    {
                        FileSystemHelper.CreateDirectory(site.LogFileDirectory);
                    }
                }

            }

            result.Result = result.Errors.Any() ? SiteResult.ValidationError : SiteResult.Success;

            return result;
        }
Beispiel #2
0
        public static ManageSiteResult CreateSite(IisSite site)
        {
            var validationResult = Validators.ValidateSite(site, null);
            if (validationResult.Errors.Any())
            {
                return validationResult;
            }

            var result = new ManageSiteResult();
            var bindingInformations = site.Bindings.Select(x => x.ToIisBindingInformation()).ToList();

            // Check bindings
            var bindingInUse = GetBindingInUse(0, bindingInformations); // 0 never exists
            if (bindingInUse != null)
            {
                result.Result = SiteResult.BindingAlreadyInUse;
                return result;
            }

            using (var manager = new ServerManager())
            {
                if (manager.Sites.Any(x => x.Name == site.Name))
                {
                    result.Result = SiteResult.NameAlreadyInUse;
                    return result;
                }

                // Create site
                manager.Sites.Add(site.Name, "http", bindingInformations.First(), site.SitePath);
                var iisSite = manager.Sites.SingleOrDefault(x => x.Name == site.Name);

                // Add bindings
                iisSite.Bindings.Clear();
                foreach (var binding in bindingInformations)
                    iisSite.Bindings.Add(binding, "http");

                // Set/create application pool
                if (string.IsNullOrWhiteSpace(site.ApplicationPool)) // Auto create application pool
                {
                    var appPoolName = site.Name;
                    var existingApplicationPoolNames = manager.ApplicationPools.Select(x => x.Name).ToList();
                    var newNameCount = 1;

                    while (existingApplicationPoolNames.Contains(appPoolName))
                    {
                        appPoolName = site.Name + "_" + newNameCount;
                        newNameCount++;
                    }

                    manager.ApplicationPools.Add(appPoolName);
                    iisSite.ApplicationDefaults.ApplicationPoolName = appPoolName;
                }
                else
                {
                    iisSite.ApplicationDefaults.ApplicationPoolName = site.ApplicationPool;
                }

                //Add Virtual apps/directories
                foreach (var application in site.Applications)
                {
                    if (!application.Path.StartsWith("/"))
                        application.Path = "/" + application.Path;

                    if (application.IsApplication)
                    {
                        if (application.Path.EndsWith("/"))
                        {
                            application.Path.Remove(application.Path.Length - 1, 1);
                        }

                        iisSite.Applications.Add(application.Path, application.DiskPath);
                    }
                    else // Directory
                    {
                        iisSite.Applications.First().VirtualDirectories.Add(application.Path, application.DiskPath);
                    }
                }

                manager.CommitChanges();

                var created = false;
                var sw = new Stopwatch();
                sw.Start();
                while (!created && sw.Elapsed.TotalSeconds < 3)
                {
                    try
                    {
                        if (iisSite.State == ObjectState.Started || iisSite.State == ObjectState.Stopped)
                        {
                            created = true;
                        }
                    }
                    catch (COMException)
                    {
                        System.Threading.Thread.Sleep(100);
                    }

                }
                sw.Stop();

                if (created)
                {
                    result.Result = SiteResult.Success;
                    result.IisSiteId = (int) iisSite.Id;
                }
                else
                {
                    result.Result = SiteResult.Failed;
                }

                return result;
            }
        }
Beispiel #3
0
        public static ManageSiteResult UpdateSite(IisSite site)
        {
            var result = new ManageSiteResult { IisSiteId = site.IisId };

            using (var manager = new ServerManager())
            {
                var iisSite = manager.Sites.SingleOrDefault(x => x.Id == site.IisId);

                if (iisSite == null)
                {
                    result.Result = SiteResult.UnknownSiteId;
                    return result;
                }

                var iisSiteWithSameName = manager.Sites.SingleOrDefault(x => x.Id != site.IisId && x.Name == site.Name);

                if (iisSiteWithSameName != null)
                {
                    result.Result = SiteResult.NameAlreadyInUse;
                    return result;
                }

                var mainApplication = iisSite.Applications.First();
                var rootPathDirectory = mainApplication.VirtualDirectories.SingleOrDefault(x => x.Path == "/");
                if (rootPathDirectory == null)
                {
                    mainApplication.VirtualDirectories.Add("/", site.SitePath);

                }
                else
                {
                    rootPathDirectory.PhysicalPath = site.SitePath;
                }

                // In some scenarios Microsoft.Web.Administation fails to save site if property-set is detected with same name.
                //I believe it deletes and insert sites on updates and this makes a name conflict. Fixed by the hack below:
                if(site.Name != iisSite.Name)
                    iisSite.Name = site.Name;

                // If the application pool does not exists on the server, create it
                if (manager.ApplicationPools.SingleOrDefault(x => x.Name == site.ApplicationPool) == null)
                {
                    manager.ApplicationPools.Add(site.ApplicationPool);
                }

                mainApplication.ApplicationPoolName = site.ApplicationPool;

                // Update log file path
                iisSite.LogFile.Directory = site.LogFileDirectory;

                // Commits bindings
                iisSite.Bindings.Clear();
                foreach (var binding in site.Bindings)
                {
                    if (binding.Protocol == Protocol.https)
                    {
                        var certificate = GetCertificates().Single(x => x.Thumbprint == binding.CertificateThumbprint);
                        iisSite.Bindings.Add(binding.ToIisBindingInformation(), certificate.Hash, "My");
                    }
                    else
                        iisSite.Bindings.Add(binding.ToIisBindingInformation(), binding.Protocol.ToString());
                }

                // Deletes virtual applications
                var applicationsToDelete = iisSite.Applications.Skip(1).Where(application => !site.Applications.Where(x => x.IsApplication).Select(a => a.Path).Contains(application.Path)).ToList();
                foreach (var application in applicationsToDelete)
                {
                    application.Delete();
                     iisSite.Applications.Remove(application); // Bug in Microsoft.Web.Administration when changing from directory - application
                }

                // Deletes virtual directories
                var directoriesToDelete = mainApplication.VirtualDirectories.Where(directory => directory.Path != "/" && !site.Applications.Where(x => !x.IsApplication).Select(a => a.Path).Contains(directory.Path)).ToList(); // Exclude "/" because it's the root application's directory.
                foreach (var directory in directoriesToDelete)
                {
                    directory.Delete();
                    mainApplication.VirtualDirectories.Remove(directory); // Bug in Microsoft.Web.Administration when changing from directory - application
                }

                //Intelligently updates virtual applications + directories
                foreach (var application in site.Applications)
                {
                    if (!application.Path.StartsWith("/"))
                        application.Path = "/" + application.Path;

                    if (application.IsApplication)
                    {
                        if (application.Path.EndsWith("/"))
                        {
                            application.Path = application.Path.Substring(0, application.Path.Length - 1);
                        }

                        var iisApp = iisSite.Applications.SingleOrDefault(x => x.Path == application.Path);

                        if (iisApp == null)
                        {
                            iisSite.Applications.Add(application.Path, application.DiskPath);
                            iisApp = iisSite.Applications.Single(x => x.Path == application.Path);
                        }

                        iisApp.VirtualDirectories[0].PhysicalPath = application.DiskPath;
                        iisApp.ApplicationPoolName = application.ApplicationPool;
                    }
                    else // Directory
                    {
                        var virtualDirectory = mainApplication.VirtualDirectories.SingleOrDefault(x => x.Path == application.Path);
                        if (virtualDirectory == null)
                        {
                            mainApplication.VirtualDirectories.Add(application.Path, application.DiskPath);
                        }
                        else
                        {
                            virtualDirectory.PhysicalPath = application.DiskPath;
                        }
                    }
                }

                manager.CommitChanges();
            }

            return result;
        }
Beispiel #4
0
        public static ManageSiteResult ValidateSite(Site site, Site originalSite)
        {
            var certificates = SiteManager.GetCertificates();

            var result = new ManageSiteResult();

            if (!site.Bindings.Any())
            {
                result.Errors.Add("Minimum one binding is required.");
            }

            if (string.IsNullOrWhiteSpace(site.Name))
            {
                result.Errors.Add("Name is required.");
            }

            var existingSite = SiteManager.GetSiteByName(site.Name);

            if (originalSite == null)
            {
                originalSite = new Site()
                {
                    IisId = 0
                };
            }

            if (site.Name != null && existingSite != null && site.Name.ToLower() == existingSite.Name.ToLower() && existingSite.IisId != originalSite.IisId)
            {
                result.Errors.Add("There's already a site with this name.");
            }

            if (string.IsNullOrWhiteSpace(site.SitePath))
            {
                result.Errors.Add("Site path is required.");
            }
            else
            {
                if (!FileSystemHelper.IsPathValid(site.SitePath))
                {
                    result.Errors.Add("Path cannot contain the following characters: ?, ;, :, @, &, =, +, $, ,, |, \", <, >, *.");
                }
                else
                {
                    if (!FileSystemHelper.DirectoryExists(site.SitePath))
                    {
                        FileSystemHelper.CreateDirectory(site.SitePath);
                    }
                }

                if (!FileSystemHelper.IsPathValid(site.LogFileDirectory))
                {
                    result.Errors.Add("Log File Directory cannot contain the following characters: ?, ;, :, @, &, =, +, $, ,, |, \", <, >, *.");
                }
                else
                {
                    if (!FileSystemHelper.DirectoryExists(site.LogFileDirectory))
                    {
                        FileSystemHelper.CreateDirectory(site.LogFileDirectory);
                    }
                }
            }

            result.Result = result.Errors.Any() ? SiteResult.ValidationError : SiteResult.Success;

            return(result);
        }
Beispiel #5
0
        public static ManageSiteResult UpdateSite(Site site)
        {
            var result = new ManageSiteResult {
                IisSiteId = site.IisId
            };

            using (var manager = new ServerManager())
            {
                var iisSite = manager.Sites.SingleOrDefault(x => x.Id == site.IisId);

                if (iisSite == null)
                {
                    result.Result = SiteResult.UnknownSiteId;
                    return(result);
                }

                var iisSiteWithSameName = manager.Sites.SingleOrDefault(x => x.Id != site.IisId && x.Name == site.Name);

                if (iisSiteWithSameName != null)
                {
                    result.Result = SiteResult.NameAlreadyInUse;
                    return(result);
                }

                var mainApplication   = iisSite.Applications.First();
                var rootPathDirectory = mainApplication.VirtualDirectories.SingleOrDefault(x => x.Path == "/");
                if (rootPathDirectory == null)
                {
                    mainApplication.VirtualDirectories.Add("/", site.SitePath);
                }
                else
                {
                    rootPathDirectory.PhysicalPath = site.SitePath;
                }

                // In some scenarios Microsoft.Web.Administation fails to save site if property-set is detected with same name.
                //I believe it deletes and insert sites on updates and this makes a name conflict. Fixed by the hack below:
                if (site.Name != iisSite.Name)
                {
                    iisSite.Name = site.Name;
                }

                // If the application pool does not exists on the server, create it
                if (manager.ApplicationPools.SingleOrDefault(x => x.Name == site.ApplicationPool) == null)
                {
                    manager.ApplicationPools.Add(site.ApplicationPool);
                }

                mainApplication.ApplicationPoolName = site.ApplicationPool;

                // Update log file path
                iisSite.LogFile.Directory = site.LogFileDirectory;

                // Commits bindings
                iisSite.Bindings.Clear();
                foreach (var binding in site.Bindings)
                {
                    if (binding.Protocol == Protocol.https)
                    {
                        var certificate = GetCertificates().Single(x => x.Thumbprint == binding.CertificateThumbprint);
                        iisSite.Bindings.Add(binding.ToIisBindingInformation(), certificate.Hash, "My");
                    }
                    else
                    {
                        iisSite.Bindings.Add(binding.ToIisBindingInformation(), binding.Protocol.ToString());
                    }
                }

                // Deletes virtual applications
                var applicationsToDelete = iisSite.Applications.Skip(1).Where(application => !site.Applications.Where(x => x.IsApplication).Select(a => a.Path).Contains(application.Path)).ToList();
                foreach (var application in applicationsToDelete)
                {
                    application.Delete();
                    iisSite.Applications.Remove(application);  // Bug in Microsoft.Web.Administration when changing from directory - application
                }

                // Deletes virtual directories
                var directoriesToDelete = mainApplication.VirtualDirectories.Where(directory => directory.Path != "/" && !site.Applications.Where(x => !x.IsApplication).Select(a => a.Path).Contains(directory.Path)).ToList(); // Exclude "/" because it's the root application's directory.
                foreach (var directory in directoriesToDelete)
                {
                    directory.Delete();
                    mainApplication.VirtualDirectories.Remove(directory); // Bug in Microsoft.Web.Administration when changing from directory - application
                }

                //Intelligently updates virtual applications + directories
                foreach (var application in site.Applications)
                {
                    if (!application.Path.StartsWith("/"))
                    {
                        application.Path = "/" + application.Path;
                    }

                    if (application.IsApplication)
                    {
                        if (application.Path.EndsWith("/"))
                        {
                            application.Path = application.Path.Substring(0, application.Path.Length - 1);
                        }

                        var iisApp = iisSite.Applications.SingleOrDefault(x => x.Path == application.Path);

                        if (iisApp == null)
                        {
                            iisSite.Applications.Add(application.Path, application.DiskPath);
                            iisApp = iisSite.Applications.Single(x => x.Path == application.Path);
                        }

                        iisApp.VirtualDirectories[0].PhysicalPath = application.DiskPath;
                        iisApp.ApplicationPoolName = application.ApplicationPool;
                    }
                    else // Directory
                    {
                        var virtualDirectory = mainApplication.VirtualDirectories.SingleOrDefault(x => x.Path == application.Path);
                        if (virtualDirectory == null)
                        {
                            mainApplication.VirtualDirectories.Add(application.Path, application.DiskPath);
                        }
                        else
                        {
                            virtualDirectory.PhysicalPath = application.DiskPath;
                        }
                    }
                }


                manager.CommitChanges();
            }

            return(result);
        }
Beispiel #6
0
        public static ManageSiteResult CreateSite(IisSite site)
        {
            var validationResult = Validators.ValidateSite(site, null);

            if (validationResult.Errors.Any())
            {
                return(validationResult);
            }

            var result = new ManageSiteResult();
            var bindingInformations = site.Bindings.Select(x => x.ToIisBindingInformation()).ToList();

            // Check bindings
            var bindingInUse = GetBindingInUse(0, bindingInformations); // 0 never exists

            if (bindingInUse != null)
            {
                result.Result = SiteResult.BindingAlreadyInUse;
                return(result);
            }

            using (var manager = new ServerManager())
            {
                if (manager.Sites.Any(x => x.Name == site.Name))
                {
                    result.Result = SiteResult.NameAlreadyInUse;
                    return(result);
                }

                // Create site
                manager.Sites.Add(site.Name, "http", bindingInformations.First(), site.SitePath);
                var iisSite = manager.Sites.SingleOrDefault(x => x.Name == site.Name);

                // Add bindings
                iisSite.Bindings.Clear();
                foreach (var binding in bindingInformations)
                {
                    iisSite.Bindings.Add(binding, "http");
                }

                // Set/create application pool
                if (string.IsNullOrWhiteSpace(site.ApplicationPool)) // Auto create application pool
                {
                    var appPoolName = site.Name;
                    var existingApplicationPoolNames = manager.ApplicationPools.Select(x => x.Name).ToList();
                    var newNameCount = 1;

                    while (existingApplicationPoolNames.Contains(appPoolName))
                    {
                        appPoolName = site.Name + "_" + newNameCount;
                        newNameCount++;
                    }

                    manager.ApplicationPools.Add(appPoolName);
                    iisSite.ApplicationDefaults.ApplicationPoolName = appPoolName;
                }
                else
                {
                    iisSite.ApplicationDefaults.ApplicationPoolName = site.ApplicationPool;
                }

                //Add Virtual apps/directories
                foreach (var application in site.Applications)
                {
                    if (!application.Path.StartsWith("/"))
                    {
                        application.Path = "/" + application.Path;
                    }

                    if (application.IsApplication)
                    {
                        if (application.Path.EndsWith("/"))
                        {
                            application.Path.Remove(application.Path.Length - 1, 1);
                        }

                        iisSite.Applications.Add(application.Path, application.DiskPath);
                    }
                    else // Directory
                    {
                        iisSite.Applications.First().VirtualDirectories.Add(application.Path, application.DiskPath);
                    }
                }

                manager.CommitChanges();

                var created = false;
                var sw      = new Stopwatch();
                sw.Start();
                while (!created && sw.Elapsed.TotalSeconds < 3)
                {
                    try
                    {
                        if (iisSite.State == ObjectState.Started || iisSite.State == ObjectState.Stopped)
                        {
                            created = true;
                        }
                    }
                    catch (COMException)
                    {
                        System.Threading.Thread.Sleep(100);
                    }
                }
                sw.Stop();

                if (created)
                {
                    result.Result    = SiteResult.Success;
                    result.IisSiteId = (int)iisSite.Id;
                }
                else
                {
                    result.Result = SiteResult.Failed;
                }

                return(result);
            }
        }