1

EPiServer: Creating sites in IIS based on the web.config

Posted on 28 February 2009 and tagged with , ,

EPiServer CMS 5 R2 SP1 is finally here. Happy times :-) The EPiServer developers have really made a quality product. However there are a few features missing in the new Deployment Center tool. One feature I'm missing is the ability to create IIS sites based on the web.config file. This becomes apparent when dealing with larger enterprise solution.

Creating EPi sites in IIS today

I have recently migrated an enterprise solution containing 20+ sites from EPiServer 4.6 to CMS 5 R2, including the required changes to the web.config file. One thing that I also did was to rename the prefixing of each sites host header like this: http://cms5.mysite.com. I did this so I could run both my original EPi 4.6 and CMS 5 sites on my local developer station. But how should I register my new sites in IIS?! The deployment center can only create new empty sites on different locations on my hard drive and upgrade existing CMS5 sites. Neither option suited my need. There are basically 2 options available when registering the new sites:

1. Use the EPiServer Deployment Center to create new sites without a database in a temp folder to avoid overwriting my exiting files. Then I had to go into IIS and fix the path on each site so that it points to my web directory. Finally I deleted the temp folders.

2. Create each site in IIS manually and then add the host headers and fix the application extension like this

Both these are quit daunting when dealing with multiple sites on multiple servers and multiple developer workstations. So i thought there is got to be an easier way to do this, preferable by some kind of script.

 

A simpler solution

Since the Deployment Center already have the ability to create and delete sites in IIS, so I thought I should take a peek at the Deployment Centers assemblies to see how the integration was done. Lo and behold, I struck gold. Thanks to the EPiServer team, who been so generous to make the methods that interacts with IIS public, I was able to create a fairly simple console app script based on the WebAppInstallationManager class in EPiServerInstall.Common1.dll.  This class can create and delete sites in both IIS 6 and IIS 7. Now I could design my own custom script by reusing existing functionality.

So here's the code. To get the sites definition from the web.config I'm using a simple Linq 2 xml query which returns the site id, host names, protocol and port information for each site. The information is stored inside a list of custom EPiSite objects.

/// <summary>
/// Extracts the site information from the site's elements in web.config
/// </summary>
/// <param name="configFile">The web.config path
/// </param>
/// <returns></returns>
public static List<EPiSite> GetSitesFromConfigurationFile(string configFile)
{
//Declaring XName variables that are used when querying the configuration file
XNamespace namespaceEPiServer = "http://EPiServer.Configuration.EPiServerSection";
XName xmlSite = namespaceEPiServer + "site";
XName xmlSiteSettings = namespaceEPiServer + "siteSettings";
XName xmlSiteHosts = namespaceEPiServer + "siteHosts";
XName xmlSiteHost = namespaceEPiServer + "add";
//Load the configuration file
XDocument configDocument = XDocument.Load(configFile);
//Extracting the site information from the configuration
var siteQuery = from site in configDocument.Descendants(xmlSite) '
select new EPiSite
{
Name = site.Attribute("siteId").Value,
SiteUrl = new Uri(site.Element(xmlSiteSettings).Attribute("siteUrl").Value),
Hosts = (from siteHost in site.Element(xmlSiteHosts).Elements(xmlSiteHost)
where siteHost.Attribute("name").Value != "*"
select new EPiHost
{
Name = siteHost.Attribute("name").Value
}).ToList()
};
List<EPiSite> sites = siteQuery.ToList();

//Add default site host to the host list (if not already existing in the host list)
foreach (EPiSite site in sites)
{
if (!site.Hosts.Exists(host => string.Equals(host.Name, site.SiteUrl.Host,
StringComparison.InvariantCultureIgnoreCase)))
{
site.Hosts.Add(new EPiHost() { Name = site.SiteUrl.Host } );
}
}

return sites;
}

The next step is to send in the each site definition into the WebAppInstallationManager which will create the site in IIS.

/// <summary>
/// Creates a site in IIS based on the provided site information
/// </summary>
/// <param name="site">The site to create</param>
/// <param name="sitePath">The physcial path of the site</param>
/// <param name="applicationPool">The application pool to connect the site to</param>
/// <returns></returns>
public static bool CreateSiteInIIS(EPiSite site, string sitePath, string applicationPool)
{
try
{
//Initialize the EPiServer installers
InstallationManager installManager = InstallationManager.Create();
WebAppInstallationManager webAppInstallManager = new WebAppInstallationManager(installManager);
//Add the IIS binding information based on provided site information
List<SiteBinding> bindings = new List<SiteBinding>();
foreach (EPiHost host in site.Hosts)
{
SiteBinding binding = new SiteBinding();
binding.Host = host.Name;
binding.Port = site.SiteUrl.Port;
binding.Protocol = site.SiteUrl.Scheme;
if (string.Equals(site.Name,host.Name,
StringComparison.InvariantCultureIgnoreCase))
{
binding.Switches.Add("default");
}

bindings.Add(binding);
}

//The EPiServer install class will do the dirty work against IIS
webAppInstallManager.CreateWebApp(site.Name, string.Empty, sitePath, applicationPool, bindings);
return true;
}
catch (Exception)
{
return false;
}
}

Simple and beautiful :-)

Click here to download the full source code

Comments (1) -

Richard says: 12/9/2010 1:53:32 AM
Richard

Great post.

Add comment




biuquote
Loading


Disclaimer

© Copyright 2009, Jarle Friestad. The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

Widget Twitter not found.

Root element is missing.X

Month List