Learn More





DNN Community Blog

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.

Module Development in DNN 8: 3 - Introduction to SPA modules

In addition to ASP.NET MVC modules, DNN 8 will support SPA (Single Page Application) modules, developed purely with HTML JavaScript and Css, together with ASP.NET Web API based Web Services on the Web Server.  DNN currently supports this module type – to a degree - but the HTML is required to be in the WebForms User Control.  A number of the newer modules have been built this way, for example the Core Messaging module and Membership modules found in the User Profile are built in this way.

In DNN 8 the requirement to use User Controls or a Razor script is removed.  Module Controls can be pure HTML files with the extension .html or .htm, and the Module injection framework will load the html into an HtmlHostControl in a similar way to how MVC modules are handled.

Setting up your Environment

We still need to create a Visual Studio project to hold our Web API classes, so the environment setup is similar to what we used for MVC modules.  In my project which is available on Github I have both modules in the same solution, so add a new Web ApplicationProject to your solution called Dnn.ContactList.Spa, choose the Empty template (1) and select Web API (2) so that the Web API references are added to your project.

Figure 1 – Creating a Web API project

As before we will be adding the same default files including a module.css file, a file and a DNN manifest file.  In addition we will need an HTML file (ContactList.html) and a JavaScript file (ContactList.js).

After adding these files and removing the unnecessary files and folders created by the template you should have something like Figure 2.

Figure 2 – The Dnn.ContactList.Spa project

There is not much to comment on in this setup. SPA modules controls The manifest looks like any normal manifest except the controlSrc property has a .html extension.  As with MVC modules the manifest should include a dependency node to indicate that the CoreVersion should be 8.0.0 or higher (see Figure 3)

Figure 3 – Sections of the Manifest file of note

  <dependency type="CoreVersion">08.00.00</dependency>

The main addition in this setup is the inclusion of the JavaScript file (ContactList.js).  This file is not required – the JavaScript can live in a different file or even in the HTML file itself, but by convention a JavaScript file with the same root name as the HTML file is automatically registered (if present)and the link added to the top of the form.  Other JavaScript files can also be registered, which will be discussed in a future post.

That's it for our SPA module development environment.  In the next blog post I will show how to display a list of Contacts in a SPA module.

For more information


2sic Daniel Mettler
Thanks Charles - this will bring DNN a huge step forward.
Will tokens automatically be resolved in the HTML?
2sic Daniel Mettler Tuesday, May 26, 2015 4:53 AM (link)
Joe Brinkman
@Daniel - Yes. Tokens are automatically resolved. This is the html from the Dynamic Content Manger which is being built using SPA module -
Joe Brinkman Tuesday, May 26, 2015 12:45 PM (link)
Abdallah Madi
Good news, we have been using this approach long time ago in modules inside user controls as a wrappers. but the main obstacle we do always face and it would be nice if DNN team could do a wrappers for them since you are approaching this way formally.

- Taxonomy and other search features connected to DNN
- Make the module crawlable for search engines, as we are using an external service to do this on the same machine PhantomJS

Also we have developed a new module using AngularJS successfully
Abdallah Madi Wednesday, July 01, 2015 10:59 AM (link)
Ravindra  Kumar
Hello Charles,
Thank You for stating the Module Development in DNN 8, While I was going through with above article ,i felt its going to be easy with MVC Module development. After reading above article , I installed DNN 08.00.00 (158) and tried to installed DnnConnect.Demo-master (Downloaded from github) with no success.

It shows the following error:


InnerMessage:Could not find file 'D:\DNN\DNN800\Install\Temp\joaqkpnh\License.txt'.


at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize, Boolean checkHost)
at System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize)
at System.IO.StreamReader..ctor(String path, Boolean detectEncodingFromByteOrderMarks)
at System.IO.File.OpenText(String path)
at DotNetNuke.Common.Utilities.FileSystemUtils.ReadFile(String filePath)
at DotNetNuke.Services.Installer.Installers.PackageInstaller.ReadTextFromFile(String source)
at DotNetNuke.Services.Installer.Installers.PackageInstaller.ReadManifest(XPathNavigator manifestNav)
at DotNetNuke.Services.Installer.Installer.ProcessPackages(XPathNavigator rootNav)
at DotNetNuke.Services.Installer.Installer.ReadManifest(Boolean deleteTemp)
at DotNetNuke.Modules.Admin.Extensions.Install.wizInstall_NextButtonClick(Object sender, WizardNavigationEventArgs e)
at System.Web.UI.WebControls.Wizard.OnBubbleEvent(Object source, EventArgs e)
at System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

I am a newbie in MVC but i have good knowledge of DNN Custom module development and till now i have developed around 100 DNN web form modules.
Please assist me with some points to starts with MVC Module Development.
Ravindra Kumar Tuesday, August 25, 2015 7:39 AM (link)
cathal connolly
@Ravindra -that error happens when you have insufficient windows permissions on your site. During install a zip package uncompresses, creating new files and folders which are then copied to the correct place. If there is a windows permission error you see a message such as that - please make sure you have read, write and modify permissions set
cathal connolly Tuesday, August 25, 2015 8:51 AM (link)
Kornelis Pieters
Also, Ravindra, make sure you 'unblock' the ZIP file after you've downloaded it, prior to attempting to install it in DNN. ZIP files downloaded from the internet are 'blocked' automatically by Windows. This can cause problems in various cases, such as installing it in DNN, although i'm not sure if it actually will; i've never tried.

You can unblock such a file by right clicking it in Windows Explorer, then clicking 'Properties'. Then you should see an 'Unblock'-button on the bottom. If that button is not there, the file wasn't blocked to begin with (meaning that my suggestion is not valid in your case, but it could of course still be the case for others).
Kornelis Pieters Tuesday, October 20, 2015 7:37 AM (link)

Comment Form

Only registered users may post comments.


2sic Daniel Mettler (124)
Aderson Oliveira (15)
Alec Whittington (11)
Alex Shirley (10)
Andrew Nurse (30)
Anthony Glenwright (5)
Antonio Chagoury (28)
Ash Prasad (22)
Ben Schmidt (1)
Benjamin Hermann (25)
Benoit Sarton (9)
Beth Firebaugh (12)
Bill Walker (36)
Bob Kruger (5)
Brian Dukes (2)
Brice Snow (1)
Bruce Chapman (20)
Bryan Andrews (1)
cathal connolly (55)
Charles Nurse (163)
Chris Hammond (203)
Chris Paterra (55)
Clinton Patterson (28)
Cuong Dang (21)
Daniel Bartholomew (2)
Dave Buckner (2)
David Poindexter (3)
David Rodriguez (2)
Doug Howell (11)
Erik van Ballegoij (30)
Ernst Peter Tamminga (74)
Geoff Barlow (6)
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 (270)
John Mitchell (1)
Jon Henning (14)
Jonathan Sheely (4)
Jordan Coopersmith (1)
Joseph Craig (2)
Kan Ma (1)
Keivan Beigi (3)
Ken Grierson (10)
Kevin Schreiner (6)
Leigh Pointer (31)
Lorraine Young (60)
Malik Khan (1)
Matthias Schlomann (15)
Mauricio Márquez (5)
Michael Doxsey (7)
Michael Tobisch (3)
Michael Washington (202)
Mike Horton (19)
Mitchel Sellers (28)
Nathan Rover (3)
Navin V Nagiah (14)
Néstor Sánchez (31)
Nik Kalyani (14)
Peter Donker (52)
Philip Beadle (135)
Philipp Becker (4)
Richard Dumas (22)
Robert J Collins (5)
Roger Selwyn (8)
Ruben Lopez (1)
Ryan Martinez (1)
Salar Golestanian (4)
Sanjay Mehrotra (9)
Scott McCulloch (1)
Scott S (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)
Timo Breumelhof (24)
Tony Henrich (3)
Torsten Weggen (2)
Vicenç Masanas (27)
Vincent Nguyen (3)
Vitaly Kozadayev (6)
Will Morgenweck (37)
Will Strohl (163)
William Severance (5)
Try Evoq
For Free
Start Free Trial
a Demo
See Evoq Live
Need More Information?