We have a EPiServer 5.x enterprise project with several sites declared in EPiServer.config
These are set up as separate websites in IIS pointing at the same webroot matching the host entry for each IIS site to the siteHosts declared for each site in EPiServer.config
<site description="Site 1" siteId="SiteOne">
<siteHosts>
<add name="www.siteone.se" language="sv" />
<add name="*"/>
</siteHosts>
<siteSettings .../>
</site>
<site description="Site 2" siteId="SiteTwo">
<siteHosts>
<add name="www.sitetwo.fi" language="fi" />
</siteHosts>
<siteSettings .../>
</site>
A problem we have been experiencing is that whenever we restart one or more of the sites in IIS and navigate to that site in a browser it (seemingly randomly) throws an error and logs:
Application is initialized with settings for siteId="SiteOne", but current request maps to siteId="SiteTwo"
if looking into the class "EPiServer.Configuration.Settings" below I can see that if the current request host does not match any of siteHost entry in EPiServer.config it will default to the siteHost site with the wildcard "*" instead.
At least one <site> section must omit the <siteHosts> section, or <add name=\"*\"> to the <siteHosts> section.
Question: Why would this happen? The sites in IIS are configured to listen to separate IP's and are bound to specific hosts.
Question: Since the EPiServer.Configuration.Settings.Instance has a public setter, would it be a good idea to be able to set this manually later? (via some .aspx or whatnot instead of restarting the application)
Of course it would be better to get a permanent fix to this instead of hacking together some half baked .aspx fix.
From the class "EPiServer.Configuration.Settings" :
public static Settings Instance
{
get
{
if (HttpContext.Current == null)
{
if (_instance == null)
{
throw new ApplicationException("First time you call Settings.Instance you must have a valid HttpContext.");
}
return _instance;
}
Settings settings = MapUrlToSettings(HttpContext.Current.Request.Url);
if (_instance == null)
{
_instance = settings;
}
else if (_instance != settings)
{
throw new ConfigurationErrorsException(string.Format("Application is initialized with settings for siteId=\"{0}\", but current request maps to siteId=\"{1}\"", _instance.Parent.SiteId, settings.Parent.SiteId));
}
return _instance;
}
set
{
_instance = value;
}
}
public static Settings MapUrlToSettings(Uri url)
{
Settings settings;
if (url == null)
{
throw new ArgumentNullException("url", "An initialized Uri instance is required.");
}
if (!url.IsAbsoluteUri)
{
throw new ArgumentException("The Uri must be absolute to use for mapping.", "url");
}
if (!string.IsNullOrEmpty(url.DnsSafeHost))
{
settings = MapHostToSettings(url.DnsSafeHost, true);
}
else
{
settings = MapHostToSettings("*", true);
}
string absolutePath = url.AbsolutePath;
string str2 = settings.SiteUrl.AbsolutePath;
if (!absolutePath.StartsWith(str2, StringComparison.OrdinalIgnoreCase) && !string.Equals(absolutePath + "/", str2, StringComparison.OrdinalIgnoreCase))
{
throw new ConfigurationErrorsException(string.Format("The URL \"{0}\" maps to siteId=\"{1}\" but has a path that is outside the application root (application root is \"{2}\").", url.ToString(), settings.Parent.SiteId, settings.SiteUrl.AbsolutePath));
}
return settings;
}
public static Settings MapHostToSettings(string hostName, bool fallback)
{
Settings settings;
if (_hostToSettings == null)
{
InitializeAllSettings();
}
if (_hostToSettings.TryGetValue(hostName, out settings))
{
return settings;
}
if (!fallback)
{
return null;
}
return _hostToSettings["*"];
}
I've encountered the same error before. I my case, we had multiple host headers configured for the sites in IIS, and one of these host headers was wrong according to the sitehosts definition in episerver.config.
If you use multiple host headers, double check them against the episerver.config files to assure they are configured on the same "sites"