navigation
 Thursday, August 09, 2007

I've been looking at the "Scheduler" entry on the DNN Host menu for quite a while now, thinking about looking into it further and wondering how I might be able to take advantage of the promise that's there.

First, the bad news: the scheduler only checks if there's a scheduled activity that needs to be run when the DNN server gets hit. So, for instance, if you have a task that you want to run every ten minutes, and nobody hits your website for three hours in the middle of the night, the task will not run until the next time there's a web request to your site. There are some DNN ways to work around this - go to http://www.dotnetnuke.com/, and search for KeepAlive, which is a module that will automatically access your website just prior to Application_End.

Now the good news: writing a scheduled service is as easy as can be, once you know the tricks. Here's the code for a complete Hello World implementation, which you should add as a new class to your App_Code folder for the project you're working on.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using DotNetNuke.Services.Scheduling;

namespace Falafel.WebPlanner
{
public class TestClass1 : SchedulerClient
{
public TestClass1(ScheduleHistoryItem objScheduleHistoryItem) : base()
{
this.ScheduleHistoryItem = objScheduleHistoryItem;
}

public override void DoWork()
{
try
{
this.ScheduleHistoryItem.Succeeded = true;
this.ScheduleHistoryItem.AddLogNote("Notification processing completed at " +
                  DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString());
}
catch (Exception exc)
{
this.ScheduleHistoryItem.Succeeded = false;
this.ScheduleHistoryItem.AddLogNote("Scheduled service failed");
this.Errored(ref exc);
}
}
}
}

Let's look at a couple of the things that are going on here. First, notice that the constructor includes a reference to a "ScheduleHistoryItem. This is used by the DNN system to pass success/failure information, as well as any messages that need to be logged. The other feature is the DoWork() method. This is the method that takes care of business for you, the method that is called every time the scheduler fires the event. Using the DoWork method as a springboard, you can accomplish anything you like programmatically.

After compiling this code into your application, the last thing you need to do is to schedule the event. Start your site from within the IDE, and log in as host. Go to the Host -> Schedule menu entry, and select "Add Item To Schedule".  The entry in the first text box is a little odd, asking you for the full class name and assembly. In the case of the example above, I enter Falafel.WebPlanner.TestClass1, App_SubCode_Falafel_WebPlanner. Set the period for the schedule to call for the time period you'd like (for the purposes of this demonstration, I chose every 15 seconds), and also (for demo purposes) select to retain schedule history for 10 iterations. Click the "Schedule Enabled" checkbox, and update.

Just to prove the point, if there's no activity on your system (and there probably should not be - you're doing this on a development system, aren't you?), leave the site alone for a minute or two. After waiting for this respectful length of time, go back to the main Host -> Schedule page, locate your entry, and click on history. You shouldn't see any more than one entry. If you click around on your website for a while, then inspect the history again, yo'll see that the scheduled events have fired on a (fairly) regular basis. Leave the site alone again for a while, and you'll notice that the events also have not fired.

In summary, the DNN scheduler is a pretty simple yet very useful tool to run scheduled tasks if either a) your site is an active one, or b) you use some method of keeping your site alive.

posted on August 9, 2007  #    by Rick Miller  Comments [0]
 Tuesday, January 09, 2007

I've written and revised a reasonable number of DotNetNuke modules, as well as Falafel's course material for DNN, and I think I can probably create binary Private Assemblies in my sleep.

I was a little unnerved, then, when I was getting something ready for an important customer this morning, and discovered some very weird and different behavior in my test environment than in the development environment. Specifically, I had written a module which collected some extended profile information from Joe User when he was logged in, which I didn't want to collect for the host user or for members of the Administrator group. So I'd upload the new module (logged in as host), then log out and go register a new user name, going immediately to the new module page, where the first thing I needed to do was enter the profile information. Dutifully, I would enter the information and submit it. And nothing would get updated. Yet this worked perfectly in my development environment.

Did I say it didn't get updated? That's not exactly true. I was feeling pretty confused, so when Lino the Wise walkd past my office, I grabbed him and said "Boss, I need some help". He listened patiently as I explained the problem, then turned to my keayboard to demonstrate.

And it worked just like it should. Lino laughed, and said it was because he was standing there that the problem got scared and went away. Then so did Lino. And the problem came right back. After a while longer, I got another coworker to come in. And again I explained the problem. And again, the program performed correctly. These two times, out of perhaps a hundred attempts.

I tried lots of things. Rebooting, of course, and iisreset. Clearing out the temporary files. Creating a fresh virtual site with the same name as the old one, then a new virtual site with a different name. Nothing worked.

I finally noticed (while doing some further testing, with a second user name) that the information from a previously logged in user was being displayed. I had been in the habit of logging in as host, uploading the new module, then logging out and immediately registering a new user. I resorted to brute force: I displayed the current user id on the form. When I'd enter and submit the new user's information, I checked and found that DNN's this.ModuleId function said I was userId=1 (host). Since I was disabling profile update through this particular page for host and administrators, my updates were getting thrown away. Apparently the couple of times it did update were when I was explaining the issue to co-workers - thus taking longer, letting the cache time out (??) and by the time I loaded the offending page, everything behaved properly.

I loaded DNN 4.4.0, and the problem went away. I had been developing and testing in DNN 4.3.5, because this was a custom job and that's what the customer was using. And the heck of it is, they (or actually, their users) will probably not ever encounter the problem because of the way the module will be used, one user at a time from computers all around the country. This particular bug hatched to frustrate only the developer. Too bad I didn't find that out more quickly...

posted on January 9, 2007  #    by Rick Miller  Comments [0]
 Friday, September 22, 2006

Written by Phillip Blanton

There seems to be a lot of trouble encountered by people attempting their first install of DotnetNuke 4.x. I have developed a step by step guide for installing a new Dnn4 development system on your Windows XP machine, and I find that I am constantly looking for the last place I posted it so that I can copy and paste it into a new thread.

I figured that Falafel would be a good place to stick it. That way I can just post a link to this one static location whenever I need to share this information.

If you follow these steps to the letter, you *WILL* have a DotNetNuke installation running on Windows XP Professional. If you want to then open and compile the solution in Visual Studio, that is the subject of another post, but let's first get you installed...

-----
Update: There is a lot of confusion about which system account needs permission to the database and directory structure of your DNN installation. It used to be "ASPNET" on non XP and Server 2000 machines, and "NETWORK SERVICE" on Windows Server 2003 machines. Now it is a little more complicated.

If you are running IIS 6, then you should use "NETWORK SERVICE". If you are using IIS 5.x, then  you should use "ASPNET". Without regard to the OS.

The rese of these instructions will refer to "ASP System Account". Please substitute either ASPNET or  "NETWORK SERVICE" as appropriate to your version of IIS.
-----

1. Unzip the DotNetNuke 4.x Source Install zip into an empty directory where it will reside on your machine. In my case that is D:\Development\WebProjects\DnnDev.

2. Right click on the DnnDev directory and select "Sharing and Security" and click the Security tab.

(If you don't have a security tab, click "Tools | Folder Options", select the "View" tab, scroll to the bottom and turn off simple file sharing. Close the dialog and repeat step 2.)

3. Click the "Add" button and in the "Enter the Object Names to Select" area, enter the necessary
ASP System Account.

4. Click the [Check Names] button and the system username will be verified and fully qualified. Click OK.

5. Select the new user account and give it "Modify" permission. It doesn't need "Full Control". Click OK.

6. Back in the WebRoot directory, Make a copy of the release.config file and rename it "web.config". Also copy the \config\SiteUrls.config file to WebRoot.

7. Open the web.config file in a text editor (Textpad is the best, so go buy it now!) I use SQLServer Developer edition and not SQL Server Express so these directions are for SQL Server.

Comment out the two SQL Express SiteSqlServer keys, and uncomment the SQL Server 2000 / 2005 ones and set the "value" element of them both as follows...

"Server=(local);Database=DnnDev;trusted_connection=yes;"

Make both SiteSqlServer keys have the same connection string. Save and close the text editor. Don't modify anything else in the web.config file.

-----
SQL Server:

 This is slightly different in SQL Server 2005 and SQLServer 2000, but the concepts are the same.

Before you create the database...

8. Start up SQL Server Enterprise Manager and expand the "Security" section. Make sure
the ASP System Account has been added to the list of "Logins" and given default access to "master".

9. Collapse the security node, right click on the "Databases" node and select "New Database". Name the database DnnDev (or whatever you called it in the connection strings in step 7). Accept all defaults and let the Enterprise Manager create the database.

10. Expand the new DnnDev database node and select "Users". Right click in the users area and select "New Database User". From the drop down list, select the
ASP System Account account you just created. Give it dbowner access. Click OK.

Close the SQL Server Enterprise Manager.

-----
IIS Administrator:

11. Open IIS Adminstrator applet and add a new virtual directory to the default website. Name it "DnnDev", point it to the
D:\Development\WebProjects\DnnDev directory. Make sure "Read" and "Run Scripts" are checked and accept all other defaults.

12. Right Click
the new website entry in IIS and click "Properties". Select the "ASP.NET" tab and make sure you are running the 2.0.50215.0 version of ASP.NET.

Setup is now complete. If there is not a problem with the system, opening up IE or Firefox and navigating to http://localhost/dnndev will instantiate the DotNetNuke installer. After the installer has completed, there will be a link at the bottom of the page that will take you to the new portal site. Installation will only run once. After which point, navigating to http://localhost/dnndev
will just display the site.

posted on September 22, 2006  #    by Lino Tadros  Comments [0]