Part 7: CommunityServer to DotNetNuke handling URLs

Part 7: CommunityServer to DotNetNuke handling URLs

So this is Part 7 of my CommunityServer to DotNetNuke blog series, unfortunately it is well over 7 months late, but better late than never I say.

This will be a quick blog post talking about “URLs” and how you can handle the old CommunityServer URLs and redirect them to the proper DotNetNuke URLs. Why would you do this? SEO, bookmarks and existing links. You want people that try to access the CS urls to be redirected properly to the appropriate DotNetNuke URL, be it for a forum post, blog post, or other.

This post isn't going to cover all the specifics, as there are too many possible variations based on the configuration of your specific website, but hopefully it will provide you an overview of how I handled things in my conversion, and get you on the way to handling them in your conversion.

Previous Posts:
Part 1: An Introduction
Part 2: DotNetNuke Installation
Part 3: Converting users from CommunityServer to DotNetNuke
Part 4: Getting the conversion tables ready for CS  to DNN
Part 5: Moving Forum threads from CommunityServer to DotNetNuke
Part 6: Community Server to DotNetNuke Moving Forum Replies and Attachments.

Assumptions

In order to do what I have done for URL handling you are going to need to purchase the URL Master module from Ifinity, you can find it here on Snowcovered. Without this you are going to have a hard time getting the URLs to work, I am sure it is possible, but I won't cover that here.

What I ended up doing for the URLs in my conversion was create an HTTPModule that I install into DotNetNuke, and then I tell URLMaster which url formats to ignore and let the HTTPModule handle the redirects for those URLs, I do this through a variety of settings. First let's cover the HTTPModule.

I also converted “blog” posts from CommunityServer into DNNSimpleArticle articles, I have an importer for that that hasn't been officially released, but the source can be found on Codeplex (github) as well. I'll try to do another blog post on using that importer, basically if I remember correctly it requires you to write a simple SQL select statement for your “source” and it will then generate Articles based on the returned results. >You can see that in action in the btnSubmit_Click event.

There are a few things in this post that aren't specific to CommunityServer, but are in for other reasons. Primarily some PHP and CGI handling. I added these in because of “hacks” or attempted hacks from various bots that were hitting the site and throwing 404 errors. I tried to do some redirection on these to pass them to a DNN page rather than letting them die. You can remove/ignore most of those if you like.

CSUrls HTTP Module

I haven't done an official release for this module, but you can go and grab the source code for the HTTPModule via Codeplex. The HTTPModule uses my standard visual studio template, so you just need to compile the code in Release mode and it will do the packaging for you (into an installable ZIP file).

The HTTPModule is a pretty simple project, there is a .DNN file that controls the installation in DNN, adding the necessary info to the web.config file.

There is also a HttpModule.cs in the Components folder that does all the work. This class could definitely use some refactoring to clean things up, but here is the basic overview of what happens in there.

First we configure a Connectionstring from the DotNetNuke web.config file, and then we create a method to get the PortalId of the existing request, this is necessary within DNN for a variety of methods.

CsRead is the primary method for the class, it does the following.

  1. Gets the PortalId
  2. Grabs the incoming URL
  3. Looks for a csdir querystring parameter that is used in the SiteURLs.config file later to designate when a URL should be parsed by the httpmodule.
  4. Looks for any CS urls that have a Tags querystring (QS) parameter and builds out a link to the DNN Search Results page
  5. Looks for CS Urls that have a PostID QS, based on the PostId we do a lookup from the DNN forum_posts table and build out a URL for that DNN forum thread.
  6. Looks for CS Urls that have a ForumID QS, build a DNN url for the appropriate Forum
  7. Looks for CS Urls that have a GroupID QS, build a DNN url for the appropriate Forum Group
  8. Look for CS Urls that have a PostName QS and then figure out the original CS post ID versus the new DnnSimpleArticle ID, build the corresponding URL
  9. At the end of all this the URL that is built from the previous steps is handled with a 301 redirection, ideally sending the person to the appropriate DNN page (URL).

URLMaster Settings

In order to get URLMaster configured properly I had a lot of trial and error in my configuration, here are the two settings I had to configure on the Host/Friendly URL page.

(useSiteUrlsRegex)

|ShowThread\.aspx|Redirect\.aspx|ShowPost\.aspx|thread/\d+\.aspx|post/\d+\.aspx|ShowForum\.aspx|
/archive/\d{4}/\d{1,2}/\d{1,2}/[a-zA-Z0-9\-\._]*?\.aspx|contact\.php|cgi-bin|forums/rss.aspx

(doNotRedirectRegex)

d+\.aspx|ShowForum\.aspx|/archive/\d{4}/\d{1,2}/\d{1,2}/[a-zA-Z0-9\-\._]*?\.aspx|contact\.php
|cgi-bin|forums/rss.aspx 

SiteURLS.config

Here is a list of changes I made to the SiteURLs.config file,

<RewriterRule>
<LookFor>.*/(\d+)/(\d+)/ShowThread.aspx</LookFor>
<SendTo>~/redirect.aspx?csdir=1&amp;PostID=$2</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>.*/(\d+)/ShowPost.aspx</LookFor>
<SendTo>~/redirect.aspx?csdir=1&amp;PostID=$1</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>.*/thread/(\d+).aspx</LookFor>
<SendTo>~/redirect.aspx?csdir=1&amp;PostID=$1</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>.*/post/(\d+).aspx</LookFor>
<SendTo>~/redirect.aspx?csdir=1&amp;PostID=$1</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>.*/(\d+)/ShowThread.aspx</LookFor>
<SendTo>~/redirect.aspx?csdir=1&amp;PostID=$1</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>.*/(\d+)/ShowForum.aspx</LookFor>
<SendTo>~/redirect.aspx?csdir=1&amp;ForumID=$1</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>.*/archive/(\d{4})/(\d{1,2})/(\d{1,2})/([a-zA-Z0-9\-\._]*?)\.aspx</LookFor>
<SendTo>~/redirect.aspx?csdir=1&amp;PostName=$4</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>.*/tags/([a-zA-Z0-9\-\._]*?)/default.aspx</LookFor>
<SendTo>~/redirect.aspx?csdir=1&amp;Tags=$1</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>.*/Forums/default.aspx?GroupId=(\d+)</LookFor>
<SendTo>~/redirect.aspx?csdir=1&amp;GroupId=$1</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>.*/Forums/rss.aspx</LookFor>
<SendTo>~/redirect.aspx?csdir=1&amp;GroupId=$1</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>.*/TabId/(\d+)(.*)/rss.aspx</LookFor>
<SendTo>~/rss.aspx?TabId=$1</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>.*Telerik.RadUploadProgressHandler.ashx(.*)</LookFor>
<SendTo>~/Telerik.RadUploadProgressHandler.ashx$1</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>[^?]*/TabId/(\d+)(.*)</LookFor>
<SendTo>~/Default.aspx?TabId=$1</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>.*BannerClickThrough.aspx(.*)</LookFor>
<SendTo>~/DesktopModules/Admin/Banners/BannerClickThrough.aspx$1</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>.*/*.php</LookFor>
<SendTo>~/phpredirect.htm</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>.*/cgi-bin/.*</LookFor>
<SendTo>~/cgiredirect.htm</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>.*/*.html</LookFor>
<SendTo>~/cgiredirect.htm</SendTo>
</RewriterRule>

Redirect.aspx

You might notice in the above SiteUrls.config changes I have a reference to redirect.aspx, I did create a simple ASPX file in the root of my website with the following contents. Basically it caught any errors that occurred, and then redirected people to a page I manually created in DotNetNuke called “newsite” that had some messages and links on the page. Basically I wanted to ensure that even if something went wrong, you still got sent to a page that provided information and links to access the new site.

<%@ Page Language="C#" AutoEventWireup="true" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
    private void Page_Load(object sender, System.EventArgs e)
    {
        try
        {
            
            
        }
        catch
        {
            string href = "https://www.sccaforums.com/newsite.aspx";
            Response.Status = "301 Moved Permanently";
            
            Response.RedirectLocation = href;
            
        }
    }
</script>

<html xmlns="https://www.w3.org/1999/xhtml">
<head runat="server">
    title SCCAForums.com
</head>
<body>
    <form id="form1" runat="server">
    <div>
    </div>
    </form>
</body>
</html>

Old URLs and New URLs

Here is an example of how the Forum URLs work in CS then in DNN.

Forum Thread
CS: www.sccaforums.com/forums/3/372507/ShowThread.aspx
DNN: www.sccaforums.com/forums/forumid/25/postid/41008/scope/posts

I intended to provide an example of how the blog urls worked as well, but in testing it looks like at least on SCCAForums.com the old blog URLs no longer work. I'll have to track down why that is, I am not TOO concerned about it, but probably should be. The reason I am not too concerned, I do know they worked for a long time, and looking around on Google I can't find any of the old URLs, so basically Google knows the new URLs and points people there. The problem I would run into is any old links for blogs, within existing blog posts, forum threads, or external sites, probably don't work.

Recent Comments

There are currently no comments. Be the first to make a comment.

Add Comment

Please add your comment by filling out the field(s) below. Your comment may need to be approved before it becomes visible.
Enter your first name for display with the comment
Enter your last name for display with the comment.
Enter your comment here.
If you can't type DNNRocks in, you can't post, plain and simple.
Submit Comment Cancel

Chris Hammond

Chris Hammond is a father, husband, leader, software developer, photographer and car guy. Chris focuses on the latest in technology including artificial intelligence (AI) and has spent decades becoming an expert in ASP.NET and DotNetNuke (DNN) development. You will find a variety of posts relating to those topics here on the website. For more information check out the about Chris Hammond page.

Find me on Twitter, GitHub and LinkedIn.