Products

Solutions

Resources

Partners

Community

Blog

About

QA

Ideas Test

New Community Website

Ordinarily, you'd be at the right spot, but we've recently launched a brand new community website... For the community, by the community.

Yay... Take Me to the Community!

Welcome to the DNN Community Forums, your preferred source of online community support for all things related to DNN.
In order to participate you must be a registered DNNizen

HomeHomeUsing DNN Platf...Using DNN Platf...Administration ...Administration ...Customizing Global.asaxCustomizing Global.asax
Previous
 
Next
New Post
9/9/2007 5:12 AM
 

Hi, John.

Could you give us a more concrete example to impl Application_Start with EventQueue?

I cannot get point from the links you provide.

Thanks,

Ricky.

 
New Post
9/10/2007 2:46 PM
 

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

 
New Post
9/10/2007 8:41 PM
 

Thanks for your thorough solution.

There are two questions I would like to further check with you:

1. You said: 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. Does this mean the HTTPContext.Current is null in a scheduled work's implementation method? I have ever found this phenomenon in my library, which create a (timer) thread to do some work.

2. The Init() of HttpModule will be executed one time once a ASP.NET application starts up?

Regards,

Ricky.

 
New Post
9/10/2007 10:08 PM
 

Ricky,

The short answer is "yes" to both your questions.

1) The scheduler is kicked off by a web request coming in. But the thread doesn't run within the context of the request. In fact, you wouldn't want that because the request is associated with a "user", even if anonymous, and you wouldn't want that context within the scheduler. Yes, HttpContext.Current will be null. Many of the DNN core methods assume a non-null context and will throw exceptions if invoked when the context is null. So you're limited in what you can do within a scheduler client.

2) Yes, the Init() method of an implementation of IHttpModule is called once when the first request comes in after a reset. If you implement BeginRequest, that will be called at the beginning of EVERY request. But Init is called once.

Lloyd

 
New Post
9/11/2007 4:19 AM
 

Thanks a million.

This let me further understand the DNN and ASP.NET

Ricky.

 
Previous
 
Next
HomeHomeUsing DNN Platf...Using DNN Platf...Administration ...Administration ...Customizing Global.asaxCustomizing Global.asax


These Forums are dedicated to discussion of DNN Platform and Evoq Solutions.

For the benefit of the community and to protect the integrity of the ecosystem, please observe the following posting guidelines:

  1. No Advertising. This includes promotion of commercial and non-commercial products or services which are not directly related to DNN.
  2. No vendor trolling / poaching. If someone posts about a vendor issue, allow the vendor or other customers to respond. Any post that looks like trolling / poaching will be removed.
  3. Discussion or promotion of DNN Platform product releases under a different brand name are strictly prohibited.
  4. No Flaming or Trolling.
  5. No Profanity, Racism, or Prejudice.
  6. Site Moderators have the final word on approving / removing a thread or post or comment.
  7. English language posting only, please.
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out