The core of the solution I came up with is the
public class VirtualSiteManager
{
public VirtualSiteManager(string defaultSiteName)
{
_defaultSiteName = defaultSiteName;
Sites = new Dictionary<string, VirtualSite>();
}
private string _defaultSiteName;
private static VirtualSiteManager _instance;
private static Type _lock = typeof(VirtualSiteManager);
public static VirtualSiteManager Instance
{
get
{
lock (_lock)
{
if (_instance == null)
{
_instance = (VirtualSiteManager) WebConfigurationManager.GetSection("virtualSite");
}
}
return _instance;
}
}
public VirtualSite DefaultSite
{
get
{
VirtualSite defaultSite = null;
if (Sites.ContainsKey(_defaultSiteName))
{
defaultSite = Sites[_defaultSiteName];
}
return defaultSite;
}
}
public Dictionary<string, VirtualSite> Sites
{
get;
private set;
}
public void AddSite(VirtualSite site)
{
if (!Sites.ContainsKey(site.Host))
{
Sites.Add(site.Host, site);
}
else
{
Sites[site.Host] = site;
}
}
public void AddSite(string name, string host, string virtualPath)
{
AddSite(new VirtualSite(name, host, virtualPath));
}
public string RewritePath(HttpContext context)
{
string host = context.Request.Url.Host;
VirtualSite handlingSite = (Sites.ContainsKey(host)) ? Sites[host]: DefaultSite;
string currentPath = context.Request.CurrentExecutionFilePath;
context.Response.AddHeader("X-Debug-currentPath", currentPath);
string returnPath = handlingSite.VirtualPath + (currentPath.StartsWith("/") ? currentPath.Substring(1) : currentPath);
if (returnPath.EndsWith("/"))
{
returnPath += "index.aspx";
}
return returnPath;
}
}
I store the domains and what their virtual path's are in the Web.Config like this:
<configSections>
<section name="virtualSite" type="RomfordEvan.Web.Components.VirtualSite.VirtualSiteHandler, RomfordEvan.Web.Components"/>
</configSections>
<virtualSite default="default">
<site name="default" host="www.domain1.com" virtualPath="/"/>
<site name="localhost" host="localhost" virtualPath="/"/>
<site name="domain2" host="www.domain2.com" virtualPath="/domain2/"/>
</virtualSite>
The
public class VirtualSiteHandler : IConfigurationSectionHandler
{
#region IConfigurationSectionHandler Members
public object Create(object parent, object configContext, System.Xml.XmlNode section)
{
XmlAttribute def = section.Attributes["default"];
string defaultSiteName = string.Empty;
if (def != null && def.InnerText.Length > 0)
{
defaultSiteName = def.InnerText;
}
VirtualSiteManager manager = new VirtualSiteManager(defaultSiteName);
XmlNodeList siteNodes = section.SelectNodes(".//site");
foreach (XmlNode siteNode in siteNodes)
{
manager.AddSite(siteNode.Attributes["name"].InnerText, siteNode.Attributes["host"].InnerText, siteNode.Attributes["virtualPath"].InnerText);
}
return manager;
}
#endregion
}
This works fine with the following caveats:
- Under IIS6 it requires wildcard mapping to the ASP.NET ISAPI filter.
- You will need to add
HttpHandler s for all the file types which your site will serve (see below)
<add verb="GET,POST" path="*/" validate="true" type="System.Web.UI.PageHandlerFactory" />
<add verb="GET" path="*.html" validate="true" type="System.Web.StaticFileHandler" />
<add verb="GET" path="*.js" validate="true" type="System.Web.StaticFileHandler" />
<add verb="GET" path="*.gif" validate="true" type="System.Web.StaticFileHandler" />
<add verb="GET" path="*.jpg" validate="true" type="System.Web.StaticFileHandler" />
<add verb="GET" path="*.png" validate="true" type="System.Web.StaticFileHandler" />
<add verb="GET" path="*.css" validate="true" type="System.Web.StaticFileHandler" />
No comments:
Post a Comment