0
Reply

Supporting multiple hosts within one ASP.NET application

BLove

BLove

Jan 27 2008 6:26 PM
1.7k
I'm trying to have one .NET app to handle many websites, and efficiency and intermingling is the biggest problem I'm facing. I'm trying to define a good foundation. The guy at dotnetkicks.net explains it perfectly what I'm trying to do: http://weblogs.asp.net/gavinjoyce/archive/2006/01/25/436436.aspx:

"You may have seen the website in the guise of www.dotnetkicks.com, but it also can be viewed from the following domains: www.kick.ie, www.javakicks.com & www.mozillakicks.com. All of these hosts are mapped to the same ASP.NET application in IIS. This has a number of benefits:

- Reduced memory footprint - there is only one IIS application running for all four hosts
- Shared cache - As the AppDomain is the same for all four websites, the cache is shared
- Ease of deployment and maintenance - we are only dealing with one deployed application. Creating new sites on new hosts is also a snap - simply add the domain mapping in IIS and add a new row in the Host table in the database

The mapping from domain to application is achieved in IIS (you can test this on your development machine by adding a few host entries in your system32\drivers\etc\hosts file):

A Host table in our database defines a number of properties of each host including the MasterPage & Theme to use (currently all sites are using the same MasterPage) and whether to show ads or not. The host information is cached in memory for quick access and this cache is accessed early in the lifecycle of each incoming page request, allowing the resulting response to be customised for the host of the request.

Any subsequent calls to the Data Access Layer will include the HostID of the current request, allowing us to tailor the data for the specific host. You can see this by using your www.dotnetkicks.com login on the other sites too."
 
After some research, I've developed some kind of direction. How's this for a good foundation?:

public static class Globals
{
    public static string SiteID
    {
        get
        {
            HttpContext.Current.Session["siteID"] =
                ConfigurationManager.AppSettings["siteID"];

            return (string)HttpContext.Current.Session["siteID"];
        }
    }

    // Site specific settings
    public static SiteSettings Site
    {
        get { return Site; }
    }
}

public static class SiteSettings
{
    public static string RootPath
    {
        get
        {
            if (HttpContext.Current.Cache[Globals.SiteID + "_rootPath"] == null)
                HttpContext.Current.Cache[Globals.SiteID + "_rootPath"] =
                    ConfigurationManager.AppSettings["UserFiles"];

            return HttpContext.Current.Cache[Globals.SiteID + "_rootPath"];
        }
    }

    public static string Files
    {
        get
        {
            if (HttpContext.Current.Cache[Globals.SiteID + "_files"] == null)
                HttpContext.Current.Cache[Globals.SiteID + "_files"] =
                    ConfigurationManager.AppSettings["UserFilesDir"];

            return HttpContext.Current.Cache[Globals.SiteID + "_files"];
        }
    }

    public static string Images
    {
        get
        {
            if (HttpContext.Current.Cache[Globals.SiteID + "_images"] == null)
                HttpContext.Current.Cache[Globals.SiteID + "_images"] =
                    ConfigurationManager.AppSettings["UserImagesDir"];

            return HttpContext.Current.Cache[Globals.SiteID + "_images"];
        }
    }

    public static string Theme
    {
        get
        {
            if (HttpContext.Current.Session["Theme"] == null)
                HttpContext.Current.Session["Theme"] =
                    ConfigurationManager.AppSettings["DefaultTheme"];

            return HttpContext.Current.Session["Theme"];
        }
    }
}
 
Then I can call the specific website's image folder, for example, like this: Globals.Site.Images. The structure I'm trying to achieve is this (notice that each sub-site has a web.config file that has it's own appsetting values). I'm hoping someone who's done this can share their experiences:

App_Code
App_Data
App_Themes
bin
Controls
Plugins
Sites
      |____site1 (http://somedomain.com)
      |     |___Files
      |     |___Images
      |     |___Templates
      |     |___Default.aspx
      |     |___Web.config
      |
      |
      |____site2 (http://elsewhere.com)
      |     |___Files
      |     |___Images
      |     |___Templates
      |     |___Default.aspx
      |     |___Web.config
      |
      |
      |____site3 (http://anotherone.com)
      |     |___Files
      |     |___Images
      |     |___Templates
      |     |___Default.aspx
      |     |___Web.config
      |
      |
      |____site4
            |___Files
            |___Images
            |___Templates
            |___Default.aspx
            |___Web.config
Web.Config

The root Web.Config won't have much appsettings except for global ones. The sub-site web.config will look something like this:

<add key="siteID" value="somedomain" />
<add key="UserFiles" value="~/sites/site1" />
<add key="UserFilesDir" value="~/sites/site1/files" />
<add key="UserImagesDir" value="~/sites/site1/imges" />
<add key="DefaultTheme" value="cherryblossom" />

Any experts have ideas on what the good approach is?

Next Recommended Forum