Hi Ricky,
Sorry I didn't see your post until now. I did implement a way to do what I wanted using Cathal's suggestion of an HttpModule. I only did it a couple weeks ago, even though I asked the question months ago! :-) Priorities. The full implementation is below. But let me explain what I needed to do so you can relate that to what you need.
We use the DNN scheduler to run processes on a daily basis to perform certain tasks. For example, we have one that checks to see if a subscription is about to expire and if it is sends an email to tell the user the subscription is up for renewal. That's just one example. Here's the issue we have: We run our application on about a dozen different machines, only one of which is the live system. Well, when the scheduled process runs, it CANNOT send users email if it is NOT the live system. We can't have users getting a dozen emails.
There are probably a lot of solutions one can come up with the solve this. Don't run it on anything but the live system. Use a ScheduleItemSetting to indicate which is the live system. Etc. I used a ScheduleItemSetting for quite a while. But we sync our live database down to several other test systems so we have good data for testing. If the setting were to be accidentally synced, ugly problem! So I was looking for a way to take out some of the human error aspect. And we still need to test, so we must run the processes on test systems.
If I know what system I'm on, that would do it. If www.live.com is my live system, then I simply do a check for that and only send email when I'm on that system. But when the DNN scheduler runs you have no HttpContext, so it's difficult to find what host you're on. My idea was to check for the host WHEN there was an HttpContext and store it away for later comparisons. That's why I asked about customizing Global.asax. If I get the host on the first web page hit, then I'll have it for later. It won't change.
Here's how I did it with an HttpModule:
using System;
using System.Web;
using DotNetNuke.Entities.Portals;
namespace MyCompany.Library.Business.Other
{
/// <summary>
/// An <c>HttpModule</c> used to initialize global settings from the HTTP context.
/// </summary>
/// <remarks>
/// <para>
/// For some functionality in the application, there is no HTTP context. For example, when the
/// DNN scheduler runs a scheduled process, it runs with a context. Sometimes certain context
/// information is necessary when there isn't a context. This information, assuming that it is
/// constant within the lifespan of the application, can be made available globally. But it must
/// come from a context.
/// </para><para>
/// This <c>HttpModule</c> is used to get context information from a valid context and save it
/// in a globally-accessible object. The logic here needs to run just once, and it will do that
/// when the very first request comes after the application starts. This all works based on one
/// large assumption, that the first request will occur before any other method runs that needs
/// to use a dynamic setting.
/// </para><para>
/// The purpose of this <c>HttpModule</c> is to eliminate the need for site-specific settings
/// where maintenance is very error prone. Site-specific settings, in the database for example,
/// can be copied when they shouldn't. This can result in disaster. By setting these "variables"
/// dynamically within the application, we don't need to worry about site-specific settings.
/// </para>
/// </remarks>
public class AppInitModule : IHttpModule
{
/// <summary>
/// Construct a default instance.
/// </summary>
public AppInitModule()
{
}
/// <summary>
/// Initialize this HttpModule.
/// </summary>
/// <remarks>
/// This method is called just once when the application starts. One-shot initialization is done
/// here. However, bear in mind that the spec isn't clear about just what context information is
/// available here. This might not work in later releases of .Net. The work done here could be
/// done in a BeginRequest event handler if necessary. But that would run for every request and
/// isn't as efficient.
/// </remarks>
/// <param name="application"><c>HttpApplication</c> object for the current application</param>
public void Init(HttpApplication application)
{
// Get Host using HttpContext because the current Request is not yet available from HttpApplication.
string host = HttpContext.Current.Request.Url.Host;
PortalAliasCollection aliases = new PortalAliasController().GetPortalAliases();
// If the host is one of the aliases, use it. If not, look through the collection for an alias that
// begins with the hostname. This will find "localhost/devdnn" when the host is "localhost" in
// development environments. It shouldn't cause other problems.
if (!aliases.Contains(host))
{
string aliasStart = host + "/";
host = null;
foreach (string alias in aliases.Keys)
{
if (alias.StartsWith(aliasStart, StringComparison.CurrentCultureIgnoreCase))
{
host = aliases[alias].HTTPAlias;
break;
}
}
}
// Save it as a global setting.
GlobalSettings.Dynamics.SetPortalAlias(host); // NOTE: THIS STORES host IN A public static VARIABLE.
}
/// <summary>
/// Perform cleanup before this instance goes away. Nothing to do here.
/// </summary>
public void Dispose()
{
}
}
}
You can replace the body of the Init method with whatever you need.
Then you need to hook this in via your web.config:
<httpModules>
<add
name="AppInit"
type="MyCompany.Library.Business.Other.AppInitModule, MyCompany.Library"/>
<add
name="UrlRewrite"
type="DotNetNuke.HttpModules.UrlRewriteModule, DotNetNuke.HttpModules.UrlRewrite"/>
.
.
.
</httpModules>
I put it as the first HttpModule, but that probably doesn't matter, unless what you're doing has dependencies on other things running first.
A cautionary note: This will run ONLY after an IIS reset (manual or automatic). It will NOT run if you go to the Host Settings page in DNN and restart the application there. If you need that, then you'll probably want to look at using the DNN queue as has been suggested.
Hope this help!
Lloyd