DNN Blog

Aug 24

Posted by: Chris Hammond
8/24/2010 4:32 PM  RssIcon

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 webservice 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, http://dnnweb.codeplex.com/

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, and why not do it in a very quick and easy way, with RESTFul implementations and JSON data that works very 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 is 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.

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

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

http://PORTALALIAS/svc/users
http://PORTALALIAS/svc/roles
http://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 code for that configuration

   1:          <component type="Config">
   2:            <config>
   3:              <configFile>web.config</configFile>
   4:              <install>
   5:                <configuration>
   6:                  <nodes>
   7:                    <node path="/configuration/system.web/httpHandlers" action="update" key="path" collision="overwrite">
   8:                      <add verb="GET" path="svc/*" type="com.christoc.dnn.dnnwebservices.Services.GetHandler, dnnwebservices" />
   9:                    </node>
  10:                    <node path="/configuration/system.webServer/handlers" action="update" key="name" collision="overwrite">
  11:                      <add name="DnnWebServicesGetHandler" verb="GET" path="svc/*" type="com.christoc.dnn.dnnwebservices.Services.GetHandler, dnnwebservices" preCondition="integratedMode" />
  12:                    </node>
  13:                  </nodes>
  14:                </configuration>
  15:              </install>
  16:              <uninstall>
  17:                <configuration>
  18:                  <nodes />
  19:                </configuration>
  20:              </uninstall>
  21:            </config>
  22:          </component>

 

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

   1:  public class GetHandler : IHttpHandler
   2:      {
   3:          #region IHttpHandler Members
   4:   
   5:          public bool IsReusable
   6:          {
   7:              get { return false; }
   8:          }
   9:   
  10:          public void ProcessRequest(HttpContext context)
  11:          {

 

In order to do the JSON side of things, which stands for JavaScript Object Notation, I pulled in an opensource library from codeplex, http://json.codeplex.com/ 

In the processing for the handler I setup some method calls, one for getting all users, get a specific user, and one for get all roles for a portal. These are pretty simple, here they are in the ProcessRequest implementation

   1:   
   2:          public void ProcessRequest(HttpContext context)
   3:          {
   4:              HttpResponse response = context.Response;
   5:              var written = false;
   6:   
   7:              //because we're coming into a URL that isn't being handled by DNN we need to figure out the PortalId
   8:              SetPortalId(context.Request);
   9:   
  10:              //get all roles for a portal
  11:              if(context.Request.Url.AbsolutePath.IndexOf("roles")>0 && written == false)
  12:              {
  13:                  response.Write(GetRolesJson(PortalId));
  14:                  written = true;
  15:              }
  16:   
  17:              //get back a listing of 
  18:              if (context.Request.Url.AbsolutePath.IndexOf("users") > 0 && written == false)
  19:              {
  20:                  response.Write(GetUsersJson(PortalId));
  21:                  written = true;
  22:              }
  23:   
  24:              //get back a single user
  25:              if (context.Request.Url.AbsolutePath.IndexOf("user") > 0 && written == false)
  26:              {
  27:                  //get the username to lookup 
  28:                  response.Write(GetUserJson(PortalId, context.Request));
  29:                  written = true;
  30:              }
  31:             
  32:          }

And the implementation of one of those calls, which goes through the DNN API

   1:          ///<summary>
   2:          /// Return all users for a portal in formatted json string
   3:          /// </summary>
   4:          /// <param name="portalId">portalid</param>
   5:          private static string GetUsersJson(int portalId)
   6:          {
   7:              //get a list of all roles and return it in json
   8:              var uc = new UserController();
   9:              var users = UserController.GetUsers(portalId);
  10:              var usersOutput = string.Empty;
  11:              foreach (var t in users)
  12:              {
  13:                  var output = JsonConvert.SerializeObject(t, Formatting.Indented);
  14:                  usersOutput += output;
  15:                  
  16:              }
  17:              return usersOutput;
  18:          }

 

And one last thing, in order to make the various calls, you also need to know how to get your PortalId based on the incoming URL.

   1:          ///<summary>
   2:          /// Set the portalid, taking the current request and locating which portal is being called based on this request.
   3:          /// </summary>
   4:          /// <param name="request">request</param>
   5:          private void SetPortalId(HttpRequest request)
   6:          {
   7:   
   8:              string domainName = DotNetNuke.Common.Globals.GetDomainName(request, true);
   9:   
  10:              string portalAlias = domainName.Substring(0,domainName.IndexOf("/svc"));
  11:              PortalAliasInfo pai = PortalSettings.GetPortalAliasInfo(portalAlias);
  12:              if (pai != null)
  13:                  PortalId = pai.PortalID;            
  14:          }
  15:   
  16:          public static int PortalId { get; set; }

 

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.

A reminder about the Hackathon, you don’t have to submit a fully flushed out 100% complete program for the contest, the idea is to do something quick and easy, and also innovative.

So get going, the Hackathon is in full swing!

7 comment(s) so far...


Gravatar

Re: Simple RESTful JSON web services with DotNetNuke

Thanks a lot for putting this together. It was a big help when working on my hackathon project. One item I ran across is that when I was setting up my app project in Appcelerator, js eval() would balk at the formatting for the json feed. Removing the formatting option in SerializeObject() fixed it for me. Thanks again.

By Adam Paxton on   8/30/2010 2:57 PM
Gravatar

Re: Simple RESTful JSON web services with DotNetNuke

Thanks for the feedback Adam, perhaps the formatting is better for Devs only, not apps :)

By Chris Hammond on   8/30/2010 2:57 PM
Gravatar

Re: Simple RESTful JSON web services with DotNetNuke

This is a great tool, thank you for sharing! I have this working on my localhost / 127.0.0.1 / local IP for DNN. However on my hosted DNN, save version of 05.06.02 (144), I have the module uploaded however the /svc/users returns a 404 error. :( Any ideas?

My DNN is loaded in the root web URL, i.e. www.betteroffhome.com, versus a ".com/dotnetnuke" if that makes a difference. I see the iWeb module that I can do similarly, however returning JSON is so much easier! Thanks for any help.

DB

By Dale Bingham on   8/2/2011 6:49 PM
Gravatar

Re: Simple RESTful JSON web services with DotNetNuke

Dale, make sure your host is using IIS7 not IIS6

By Chris Hammond on   8/2/2011 6:49 PM
Gravatar

Re: Simple RESTful JSON web services with DotNetNuke

Have you implemented the POST verb in your web.config file? The example project only has a GET method

By Chris Hammond on   11/25/2011 8:37 PM
Gravatar

Re: Simple RESTful JSON web services with DotNetNuke

Hey

Sorry for the delayed reply as I need to get few things done for that project. But your point worked.

Thank you Chris!

It worked like a charm! I missed that some how.

By kanav_DNN on   11/29/2011 10:26 PM
Gravatar

Re: Simple RESTful JSON web services with DotNetNuke

Kanav, I would suggest looking at google regarding your error, that is completely outside the scope of this blog post

By Chris Hammond on   12/16/2011 10:15 AM
Attend A Webinar
Free Demo Site
Download DotNetNuke Professional Edition Trial
Have Someone Contact Me
Have Someone Contact Me

Like Us on Facebook Join our Network on LinkedIn Follow DNN Corporate on Twitter Follow DNN on Twitter

Advertisers

Sponsors

DotNetNuke Corporation

DotNetNuke Corp. is the steward of the DotNetNuke open source project, the most widely adopted Web Content Management Platform for building web sites and web applications on Microsoft .NET. Organizations use DotNetNuke to quickly develop and deploy interactive and dynamic web sites, intranets, extranets and web applications. The DotNetNuke platform is available in a free Community and subscription-based Professional and Enterprise Editions with an Elite Support option. DotNetNuke Corp. also operates the DotNetNuke Store where users purchase third party apps for the platform.