When DotNetNuke was first conceived, one of the original goals was that it needed to be a web application which could be easily customized and extended with additional functionality. This was critically important to me because in my professional career I had learned that software projects are never “finished”; rather, they are living, breathing organisms which are constantly evolving and growing to accommodate new business scenarios. This fundamental understanding led to the development of a modular, loosely coupled architecture which is still a foundational pillar of the DotNetNuke platform today.
So like most software developers, once I deliver a technical solution to a business problem I usually move immediately on to the next challenge. This is usually out of necessity as the backlog is never idle, but it generally means that technology which may have a broader use for other developers in the organization or community at large is isolated in a website or code repository where it will never see the light of day. Over the years, I have written plenty of such code for internal purposes and I recently thought it might be interesting to browse through the archives for any gems which could be shared with the DNN developer community.
K.I.S.S. is an acronym for “Keep It Simple Stupid”. Four little words of wisdom which can be applied to almost any situation and in my career I have definitely learned that the simplest technical solution is almost always the best solution. The simplest solution is easier to define, easier to develop, and easier to maintain and adapt in the long term. And as long as it solves the primary goal, I have found that the exception cases are often not worth accommodating once you consider the return on investment. When it comes to DotNetNuke, I have noticed that some developers like to build “kitchen sink” solutions – sophisticated modules that can be configured to perform a variety of website functions. Personally, I prefer the approach of building multiple modules- each with a very simple, well defined purpose.
One such “simple” module I came across while browsing my archive is a User Redirect module. The User Redirect module does exactly what its name describes, it allows you to specify criteria for redirecting a website visitor to a specific landing page on your site. Integration with the security roles and social groups aspects of DotNetNuke, allows you to take advantage of the organizational structure of your website to create workflows that improve the user experience for your users. And even though the solution is simple, it is also very flexible in terms of allowing you to define a variety of redirect rules for different purposes within the same site.
From a technical perspective, there is one aspect of this module which is not typical of most DotNetNuke modules – that is, its primary view is “invisible”. I refer to these types of modules as “non-visual modules” as although they are part of a standard page on a DotNetNuke website, their main purpose is to perform server-side processing, and as a result they do not have any user interface elements which are rendered to the client browser ( unless you are a Page Editor ). Non-visual modules are not highly common but they do serve a useful purpose in terms of providing advanced server-side processing, which is one of the benefits of utilizing a web framework like ASP.NET.
The User Redirect module was originally written for DotNetNuke 3.x so I decided to update it to take advantage of the new user interface form pattern in DotNetNuke 6.x, including modal popups and styling. This was very straightforward and completely modernized its appearance. I also converted the code from VB to C# and in the process realized that all of the original module logic which called DotNetNuke core APIs did not need to be modified at all as the DotNetNuke framework still supports all of the functions it utilizes. This module was developed using a dynamic approach which means it is simply comprised of two ASP.NET user controls, without any need for other project artifacts or compilation. The benefit to developing modules using this method is that there is no complicated configuration required to set up the module, its dependencies, or its build environment. You simply write your code in the user control and test your efforts in real-time; so there is also no down-time waiting for manual compilations tasks to complete in the IDE. The module does not have elaborate needs for storing data so it takes advantage of the core ModuleSettings API to store key/value pairs of data for the module in a simple, secure, and scalable table structure.
Most of the core logic for the module exists in the OnLoad() event of the View control:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (!Page.IsPostBack)
{
//Load redirect configuration from module settings
…
//Editors need to be able to configure the module
if (ModulePermissionController.HasModulePermission(ModuleConfiguration.ModulePermissions,"Edit"))
{
//Display the redirect configuration details to the module editor
…
lblRedirect.Text = redirectMessage ;
}
else
{
//Evaluate redirect configuration and consider the &noredirect parameter
if (Request.QueryString["noredirect"] == null && (PortalSecurity.IsInRole(roleName)))
{
// Redirect the user
Response.Redirect(…);
}
else
{
//Make module invisible
ContainerControl.Visible = false;
}
}
}
}
As you can see the code is very simple because it utilizes the richness of the DotNetNuke platform for security and page processing. And from an administration perspective, the module takes advantage of the Supports Popups? option in the extension configuration area to provide a modern user experience that is consistent with the rest of the DotNetNuke application, without having to write any code.
Once a User Redirect module is added to a page, it behaves like any other DotNetNuke module. This means that the module instance can be shared across multiple pages in your site, or it can even be included on all pages if you want to implement a global workflow. Some use cases I used it for in the past was to redirect Unauthenticated users to a Login page, redirect Authenticated users to a “Welcome” dashboard page, and redirecting an employee to a departmental landing page for their function. If you have multiple rules, you can include multiple User Redirect modules on a page and they will be processed in the order in which they are organized.
Some of the more advanced functionality of this module provides support for a “noredirect” querystring parameter. If this parameter is included on the URL of the page request, the user will be able to access the page and bypass the redirect rule. This is sometimes helpful for administrating the page or supporting more complex workflows. Another feature is to optionally include your own custom querystring parameters which will be passed on the redirect URL to the target page. Custom querystring parameters can include dynamic tokens for [USERID], [ROLEID], and [TABID] which will dynamically substitute the value of the parameter at run-time based on the user context.
I hope you find this module useful in building your DotNetNuke websites and applications – both from an end user and software development perspective. I will continue to browse my archive for other useful nuggets which may have broader use in the community.