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.

Getting Started with Services Framework WebAPI Edition

In DotNetNuke 7 the Services Framework has been updated to be based on the new WebAPI stack instead of ASP.Net MVC. Switching to WebAPI is a great thing for the Services Framework, primarily because WebAPI is built from the ground up as a tool for writing web services on HTTP. MVC was a pretty decent way to build web services, but it was never specifically intended for the task. This post will layout the basic Hello World service implementation. A future post will explain how to convert an existing MVC based controller to WebAPI.

Creating a web service with Services Framework is very easy. Before you begin, ensure that you have installed the 7.0 CTP2 or the final release when it is available.

The next step is to setup a new class library project with references to all the appropriate libraries.

  1. In Visual Studio create a new class library project for .Net Framework 4.0
  2. Add references to the following libraries in your installation (Browse to the /bin folder of you install using the Add Reference dialog box)
    • DotNetNuke.dll
    • DotNetNuke.Web.dll
    • System.Net.Http.dll
    • System.Net.Http.Formatting.dll
    • System.Web.Http.dll
  3. Add references to the following standard .Net libraries (Use the .Net tab of the Add Reference dialog box)
    • System.Web
  4. Set the output path of your project to the /bin folder of your 7.0 installation
  5. Delete the default Class1.cs file

Now you are ready to write your own controller, add a new class with the following code:

using System;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using DotNetNuke.Web.Api;

namespace MyServices
    public class WelcomeController : DnnApiController
        public HttpResponseMessage HelloWorld()
            return Request.CreateResponse(HttpStatusCode.OK, "Hello World!");

The first important detail in this code snippet is the class name. WebAPI requires that the name of all controllers end with the word Controller hence the name of our class WelcomeController. Without the Controller at the end of the name the service will not work.

The next thing to take note of is that we have inherited from DnnApiController. This is very similar to the WebAPI ApiController class but adds the various DotNetNuke framework integrations such as authentication, and access to portal settings.

You will notice that the method returns a HttpResponseMessage. With such a simple method we could have simply returned a string, but using HttpResponseMessage is a good habit to build as it will provide much more flexibility when writing services that need to return more than just a simple OK response.

The HelloWorld method also has two attributes. The HttpGet attribute allows the method to be accessed from Get requests. The final important detail is the use of the AllowAnonymous attribute. Authorization is one area where the DotNetNuke Services Framework deviates substantially from WebAPI. A standard WebAPI service essentially leaves all the methods open to anonymous access by default, and then various Auth filter are applied to tighten that access where needed. DotNetNuke has taken the opposite approach, by default all methods require Host level authorization, and then various Auth filters are applied to loosen that access where needed. In this case we want to allow anonymous access to our HelloWorld service.

The service itself is pretty simple, the only remaining question is what URL to use to call this service. Those familiar with WebAPI will know that you must setup a route to make the methods on your controllers accessible to the web. Create another class and insert the following code:

using System;
using DotNetNuke.Web.Api;

namespace MyServices
    public class RouteMapper : IServiceRouteMapper
        public void RegisterRoutes(IMapRoute mapRouteManager)
            mapRouteManager.MapHttpRoute("MyServices", "default", "{controller}/{action}", new[] {"MyServices"});

Traditionally routing is done inside Global.asax. It would be very messy to update Global.asax for every service installed in a DotNetNuke site so instead we create the IServiceRouteMapper interface. This interface allows you to register routes in a fashion very similar to WebAPI. All routes for the Services Framework will be mapped to the following structure:


Here is a break down of each of the parameters passed to IMapRoute.MapHttpRoute:

"MyServices" - string moduleFolderName: Unique to DNN this parameter should be a name unique to your module/service, and will typically match the name of the DesktopModules folder in which your module is installed. It is important to use a name unique to your service to avoid routing conflicts with other services that may be installed.

"default" - string routeName: A name for your route.  This makes up part of the total route name when routes are registered in ASP.Net.  The combination of moduleFolderName and routeName must always be unique.  This name is important when trying to use the UrlHelper extensions.  For most services that only use a single route, "default" is perfectly acceptable.

"{controller}/{action}" - string url: Standard WebAPI parameter that defines the unique characteristics of your route.

"new [] {"MyServices"} = string[] namespaces: Unique to DNN, this is an array of namespaces to search for controllers for this route. The parameter helps prevent conflict between services built by different developers.

Now compile the code and all that remains to do is to test your service. There is no installation or registration require for Services Framework, as long as the .dll is present in the /bin folder the service will be setup when the site starts. See step 4 above if the .dll is not in the website's /bin folder after the compilation.

To test the service simply open a browser to ~/DesktopModules/MyServices/API/Welcome/HelloWorld and your browser should load a page that says "Hello World!".

That is all there is to building a basic service using DotNetNuke Services Framework in 7.0. Stay tuned for more posts with all the details...

I recommend following the instructions in this example to create a working service, but the code can also be found on github.

Finally you can also find more documentation on the Service Framework in DotNetNuke 7 in the Wiki.


Yehuda Tiram
Thank you for this very good explanation.
One comment though, regarding the path of the service. You set the path to call the service with some capital letters in it. I found that if you call the service from jQuery code you must set all the letters to none capitals.
Yehuda Tiram Thursday, September 05, 2013 4:14 AM (link)
Berney Villers
How can this be taken one step further? I am now a couple of days into trying to authenticate into a DNN Service using httpclient in another app. Every step of the way I run into a new roadblock. I am currently stumped with the problem of DNN 7 having hashed passwords by default. This causes httpclient and httpwebrequest calls (standard mechanisms for accessing a web service) to fail with the 500 server error - password cannot be retrieved.

This makes sense given that hashed passwords cant be retrieved, but how exactly is it that a DNN service can be used outside of DNN then?
Berney Villers Monday, September 09, 2013 5:09 AM (link)
Ankur Rajput
Scott Schlesier,
Thank you for sharing great approch. Can you please post an example for [HttpPost] request? How can we use the [HttpPost] request parameters in controller file?Is there any specific approach for this?

Ankur Rajput Friday, April 04, 2014 1:37 AM (link)
Scott Schlesier,
Can you please post an example for [HttpPost],[HttpPut] and [HttpDelete] requests? How can we use these requests with parameters from application where WebApi is not hosted? Is there any specific approach for this?

MASOOD AHMED Saturday, April 26, 2014 5:42 AM (link)
Robert Mckimmey
How very poor this reflects upon you and your organization, Scott, for not getting back to these people who are trying to understand your product and help YOU and YOUR ORGANIZATION be better.

How about responding to them.

Can you blame them if they moved on to another platform that gave a crap about them?

Shaun, are you seeing this?
Robert Mckimmey Friday, August 01, 2014 4:52 PM (link)
cathal connolly
@Robert - Scott left DNN Corp a few years for personal reasons (moved to a different country and a change in family circumstances) and I doubt he monitors this blog anymore - in general if you have questions I recommend or as not many people will notice a question in a comment on a blog (I only did as I moderate blog comments)
cathal connolly Saturday, August 02, 2014 11:01 AM (link)
Ainsof So'o
@Berney @cathal Did anyone find a working example? I've been searching for 3 days and havent found anything that works. It only works if I use [AllowAnonymous] which is an absolutely no no .

I wish I could just use basic authentication instead of digest ???

Otherwise I'll just use plain Web Api and scrap DNN
Ainsof So'o Sunday, July 03, 2016 8:50 PM (link)
Alan Avante
If it is true that comments are no longer responded to, why not stop allowing comments? The largest problem I have always had with DNN is the ridiculous moderation of a free product. I mean, it's not like people are going to spam you with complaints, when the product is excellent and FREE! So why the moderation, especially after TWELVE YEARS! It would improve your customer satisfaction like no other move. I asked two questions so far and have yet to even see them show up. That's ridiculous
Alan Avante Sunday, July 24, 2016 1:39 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 (21)
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 (268)
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?