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!

The Community Blog is a personal opinion of community members and by no means the official standpoint of DNN Corp or DNN Platform. This is a place to express personal thoughts about DNNPlatform, the community and its ecosystem. Do you have useful information that you would like to share with the DNN Community in a featured article or blog? If so, please contact .

The use of the Community Blog is covered by our Community Blog Guidelines - please read before commenting or posting.

HowTo: Set up a Private Download Area with Logging

Just recently, a client asked me to setup a download area with selected documents, where users should have to provide name and a few other information, being able to download the files.

As he already uses DNN Form and List module a lot and asked for a kind of Master – Detail design, I choose using this module, I created a new instance on the page, and adjusted module settings to inclue the following fields:

  • Title (Text)
  • Description (RichText)
  • DownloadFile (download file)
  • Created At and By as well as Last Updated At and By columns are provided by FnL module automatically.

I applied the appropriate custom views and granted access to “All Users”

I also created a folder of type “Secure (File System")” for uploading the pictures to, which has view permission granted to “Registered Users” role only.

This way, users, who click the Download link, have to login first – I added appropriate text on the (custom) download page. I Admin > Site Settings, I set up a proper registration form, including all the information required: Email, Password, PasswordConfirm, First Name, LastName and Company (all set to be required). DisplayName is defined to be created by “[FirstName] [LastName] and Email is used for login.
Now users may click on the download link, get presented a login dialog (if not already logged in) with a register option, which is explained in a text module on the same page.

This configuration was accepted by the client, however, he wants to be able to see, who downloaded which document. Now, Form and List module does provide the download datatype, which has the option of recording clicks, but due to the lack of UI (especially for multiple download columns), we skipped to implement this option, when we added this data type a few years ago. Now, when using LinkClick.aspx (as FnL download datatype does), DNN has the option to track the number of clicks and even record each click in the database. it uses table UrlTracking, where for a Module and URL, Track and Log options are stored as well as in table UrlLogging, where each download is tracked, if tracking is unabled.

DNN FnL module does create a record in UrlTracking for each URL, however, tracking and logging are turned off. To turn it on automatically. I had to find out the moduleID first. it is usually displayed in URL, when entering settings. FnL stores all data serialized in table UserDefinedData (the name is caused by historical reasons). Each value stored is identified by rowId and fieldID. To get the fieldID, I need to query the database, using my moduleID (456 in this case), in Host > SQL:

SELECT UserDefinedFieldId, FieldTitle, ModuleID FROM UserDefinedFields WHERE ModuleID = 456

This lists all column definitions for the module, including title. I noted down the UserDefinedFieldId for my download column (4007 in my case). Now I was able to place a trigger on the table, where data is stored. A table trigger in SQL Server is a piece of SQL code, which is executed, whenever a row is inserted, deleted and/or updated. To create the trigger, I ran the following SQL script:

CREATE TRIGGER [dbo].[UDT_LogDownloads] 
   ON  [dbo].[UserDefinedData]

	MERGE INTO UrlTracking T USING (SELECT FieldValue FROM UserDefinedData WHERE UserDefinedFieldID = 4007) U ON T.URL = U.FieldValue
	WHEN MATCHED AND (LogActivity = 0 OR TrackClicks = 0) THEN UPDATE SET LogActivity = 1, TrackClicks = 1
	WHEN NOT MATCHED THEN INSERT (PortalID, URL, UrlType, LogActivity, TrackClicks, ModuleID) VALUES (0, U.FieldValue, 'F', 1, 1, 5930);

Now, all download clicks are logged, but there is no UI, to display the download list. For this purpose, I used DNN Reports module.
I placed an instance on the page and restricted visibility to admins only. The users wants a list including Download File name, user email, user displayName and user company
Custom properties like Company are stored in UserProfile table, using PropertyDefinitionID , which I had to lookup in PropertyDefinition table by running the following SQL statement:

SELECT * FROM ProfilePropertyDefinition WHERE ModuleID = 456 AND PropertyName = ‘Company’. 

Using the information of PropertyDefinition = 43, I used the following statement  in report settings, to display all downloads within the past year (sorted by date descending):

SELECT F.FileName, L.ClickDate, U.DisplayName, U.Email, P.Company

FROM UrlTracking T

JOIN Files       F ON SubString(T.Url, 8, 11) = Convert(nVarChar(11), F.FileID)
JOIN UrlLog      L ON T.UrlTrackingID = L.UrlTrackingID

JOIN Users       U ON L.UserID = U.UserID
LEFT JOIN (SELECT UserID, PropertyValue AS Company FROM UserProfile WHERE PropertyDefinitionID = 43) P ON U.UserID = P.UserID

WHERE L.ClickDate > DateAdd(YY, -1, GetDate())


Now my client is happy with his download section and list of downloads.

Q: why don’t you use DNN Documents module?
A: the module is easy, if you are happy with the columns provided and the layout. I needed to implement a specific design for the client, to integrate with his CD (Corporate Design).

Q: Am I able to send an email, whenever the download link is clicked
A: yes, but for doing this without coding, you need to configure SQL Server to send emails and creae an insert trigger for your UrlLog table.


Horacio Judeikin
Why not the Evotiva DNN UserFiles module? It is not free, but the implementation, user experience and design (100% custom) would be a real time saver. :)
Horacio Judeikin Monday, December 1, 2014 5:51 PM (link)
Sebastian Leupold
thanks for pointing to your module and I see a number of valid use cases for it.
In this case, I needed the option for a file description to be displayed abouve the download link.
The other Feature request was the download report with user details.
Sebastian Leupold Tuesday, December 2, 2014 2:58 AM (link)
Horacio Judeikin
Hi Sebastian.

> I needed the option for a file description to be displayed above the download link.
This is supported by UserFiles. [UserFiles:ItemTitle] would be the (optionally editable) description, and the [UserFiles:Download] (with its variations - token.

> the download report with user details.
Downloads tracking (with a report) is a built-in (optional) feature.
Horacio Judeikin Tuesday, December 2, 2014 12:10 PM (link)
Craig Mitchell
I use . Logging works well etc logs to a table. Only enhancement I would ask for is that when logging is enabled for a user to have access to the log file.
Craig Mitchell Wednesday, December 3, 2014 6:27 AM (link)
Sebastian Leupold
Guys, thanks for your comments and recomendations.

I am well aware, there are a number of 3rd party documents modules, which support logging - but not with same options for design and additional fields, as free Form and Lists module provides.
Sebastian Leupold Wednesday, December 3, 2014 7:09 AM (link)

Comment Form

Only registered users may post comments.


Aderson Oliveira (22)
Alec Whittington (11)
Alessandra Daniels (3)
Alex Shirley (10)
Andrew Hoefling (3)
Andrew Nurse (30)
Andy Tryba (1)
Anthony Glenwright (5)
Antonio Chagoury (28)
Ash Prasad (37)
Ben Schmidt (1)
Benjamin Hermann (25)
Benoit Sarton (9)
Beth Firebaugh (12)
Bill Walker (36)
Bob Kruger (5)
Bogdan Litescu (1)
Brian Dukes (2)
Brice Snow (1)
Bruce Chapman (20)
Bryan Andrews (1)
cathal connolly (55)
Charles Nurse (163)
Chris Hammond (213)
Chris Paterra (55)
Clint Patterson (108)
Cuong Dang (21)
Daniel Bartholomew (2)
Daniel Mettler (181)
Daniel Valadas (48)
Dave Buckner (2)
David Poindexter (12)
David Rodriguez (3)
Dennis Shiao (1)
Doug Howell (11)
Erik van Ballegoij (30)
Ernst Peter Tamminga (80)
Francisco Perez Andres (17)
Geoff Barlow (12)
George Alatrash (12)
Gifford Watkins (3)
Gilles Le Pigocher (3)
Ian Robinson (7)
Israel Martinez (17)
Jan Blomquist (2)
Jan Jonas (3)
Jaspreet Bhatia (1)
Jenni Merrifield (6)
Joe Brinkman (274)
John Mitchell (1)
Jon Henning (14)
Jonathan Sheely (4)
Jordan Coopersmith (1)
Joseph Craig (2)
Kan Ma (1)
Keivan Beigi (3)
Kelly Ford (4)
Ken Grierson (10)
Kevin Schreiner (6)
Leigh Pointer (31)
Lorraine Young (60)
Malik Khan (1)
Matt Rutledge (2)
Matthias Schlomann (16)
Mauricio Márquez (5)
Michael Doxsey (7)
Michael Tobisch (3)
Michael Washington (202)
Miguel Gatmaytan (3)
Mike Horton (19)
Mitchel Sellers (40)
Nathan Rover (3)
Navin V Nagiah (14)
Néstor Sánchez (31)
Nik Kalyani (14)
Oliver Hine (1)
Patricio F. Salinas (1)
Patrick Ryan (1)
Peter Donker (54)
Philip Beadle (135)
Philipp Becker (4)
Richard Dumas (22)
Robert J Collins (5)
Roger Selwyn (8)
Ruben Lopez (1)
Ryan Martinez (1)
Sacha Trauwaen (1)
Salar Golestanian (4)
Sanjay Mehrotra (9)
Scott McCulloch (1)
Scott Schlesier (11)
Scott Wilkinson (3)
Scott Willhite (97)
Sebastian Leupold (80)
Shaun Walker (237)
Shawn Mehaffie (17)
Stefan Cullmann (12)
Stefan Kamphuis (12)
Steve Fabian (31)
Steven Fisher (1)
Tony Henrich (3)
Torsten Weggen (3)
Tycho de Waard (4)
Vicenç Masanas (27)
Vincent Nguyen (3)
Vitaly Kozadayev (6)
Will Morgenweck (40)
Will Strohl (180)
William Severance (5)
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out