· Chris Hammond
Last Updated

Simple RESTful JSON web services with DotNetNuke

Learn how to quickly add a RESTful JSON webservice to your modules for mobile apps in this detailed guide. Get coding tips and sample code snippets!

Learn how to quickly add a RESTful JSON webservice to your modules for mobile apps in this detailed guide. Get coding tips and sample code snippets!

In case you missed it, there is a hackathon that is going on right now (the submission deadline is tomorrow, so you still have time to throw a quick mobile project together).

As part of the hackathon event in St. Louis last week, I gave a brief presentation on how to quickly and easily add a RESTful JSON web service to your modules, or even create a simple module to do this yourself. I have the source code for this presentation on Codeplex under the dnnweb project:
https://github.com/ChrisHammond/

The idea behind this is that in order to create a mobile app that does something with DNN, you likely need to expose some data. Why not do it in a very quick and easy way with RESTful implementations and JSON data that works well with JavaScript? For an example project, you should check out the DNN Pulse application that Joe blogged about earlier.

The code is in C#, but it’s really simple—you should be able to get it into a VB project fairly easily. In this post, I’m going to talk about the code and what is going on.

Security Warning

One word of warning: this project that you can download and install is not using any type of authentication right now. If you add it to a site and someone calls svc/users, they will get a list of all your users. It is just provided for sample purposes at the moment.

Configuring Web Services in web.config

The first thing is a quick modification to your web.config file. If you’re using IIS7, you can easily set up an HTTPHandler that will allow your web service to respond to incoming requests, such as:

https://PORTALALIAS/svc/users      
https://PORTALALIAS/svc/roles       
https://PORTALALIAS/svc/user/USERNAME

With DNN5, this becomes very easy to do in your module’s manifest file. With the project linked above, I have already made this change for you. Here’s the sample configuration:

<component type="Config">
  <config>
    <configFile>web.config</configFile>
    <install>
      <configuration>
        <nodes>
          <node path="/configuration/system.web/httpHandlers" action="update" key="path" collision="overwrite">
            <add verb="GET" path="svc/*" type="com.christoc.dnn.dnnwebservices.Services.GetHandler, dnnwebservices" />
          </node>
          <node path="/configuration/system.webServer/handlers" action="update" key="name" collision="overwrite">
            <add name="DnnWebServicesGetHandler" verb="GET" path="svc/*" type="com.christoc.dnn.dnnwebservices.Services.GetHandler, dnnwebservices" preCondition="integratedMode" />
          </node>
        </nodes>
      </configuration>
    </install>
    <uninstall>
      <configuration>
        <nodes />
      </configuration>
    </uninstall>
  </config>
</component>

Setting Up the HTTP Handler

The next thing you need to do is set up the HTTPHandler itself. In the example code, I set up the GetHandler, which exists in Services/GetHandler.cs. You basically need to implement IHttpHandler on the class.

public class GetHandler : IHttpHandler
{
    public bool IsReusable => false;

    public void ProcessRequest(HttpContext context)
    {
        HttpResponse response = context.Response;
        var written = false;

        SetPortalId(context.Request);

        if (context.Request.Url.AbsolutePath.Contains("roles") && !written)
        {
            response.Write(GetRolesJson(PortalId));
            written = true;
        }

        if (context.Request.Url.AbsolutePath.Contains("users") && !written)
        {
            response.Write(GetUsersJson(PortalId));
            written = true;
        }

        if (context.Request.Url.AbsolutePath.Contains("user") && !written)
        {
            response.Write(GetUserJson(PortalId, context.Request));
            written = true;
        }
    }
}

JSON Implementation

To handle JSON, I used an open-source library from Codeplex:
https://json.codeplex.com/

Here’s an example method that retrieves all users for a portal and returns the data as a JSON string:

private static string GetUsersJson(int portalId)
{
    var users = UserController.GetUsers(portalId);
    return JsonConvert.SerializeObject(users, Formatting.Indented);
}

Getting the Portal ID

You also need to determine the PortalId based on the incoming request:

private void SetPortalId(HttpRequest request)
{
    string domainName = DotNetNuke.Common.Globals.GetDomainName(request, true);
    string portalAlias = domainName.Substring(0, domainName.IndexOf("/svc"));
    PortalAliasInfo pai = PortalSettings.GetPortalAliasInfo(portalAlias);
    
    if (pai != null)
        PortalId = pai.PortalID;
}

public static int PortalId { get; set; }

Final Thoughts

The rest of the module project right now doesn’t do anything. Eventually, I will add authentication and some display functionality to the services and the module, but for now, it’s just something quickly put out there. Download it, tear it apart, and start working on your own web services.

Reminder About the Hackathon

You don’t have to submit a fully polished, 100% complete program for the contest. The idea is to do something quick, easy, and innovative.

So get going—the hackathon is in full swing!

Back to Blog

Related Posts

View All Posts »

15 Years of DotNetNuke

Discover the journey of DotNetNuke's evolution from IBuySpy Workshop, thanks to Shaun Walker. Learn how it transformed Microsoft's approach to Open Source.