I've been trying to learn different patterns of programming, and the "Chain of Responsibility" sort of eludes me. I've been told that my specific code snippet would be a good candidate for chain of responsibility, and I'm wondering if someone could show me how to get there?
Public Overrides Sub OnActionExecuting(ByVal filterContext As ActionExecutingContext)
''# Set a local variable for the HttpContext.Request. This is going to
''# be used several times in the subsequent actions, so it needs to be
''# at the top of the method.
Dim request = filterContext.HttpContext.Request
Dim url As Uri = request.Url
''# Now we get the referring page
Dim referrer As Uri = If(Not request.UrlReferrer Is Nothing, request.UrlReferrer, Nothing)
''# If the referring host name is the same as the current host name,
''# then we want to get out of here and not touch anything else. This
''# is because we've already set the appropriate domain in a previous
''# call.
If (Not referrer Is Nothing) AndAlso
(Not url.Subdomain = "") AndAlso
(Not url.Subdomain = "www") AndAlso
(referrer.Host = url.Host) Then
Return
End If
''# If we've made it this far, it's because the referring host does
''# not match the current host. This means the user came here from
''# another site or entered the address manually. We'll need to hit
''# the database a time or two in order to get all the right
''# information.
''# This is here just in case the site is running on an alternate
''# port. (especially useful on the Visual Studio built in web server
''# / debugger)
Dim newPort As String = If(url.IsDefaultPort, String.Empty, ":" + url.Port.ToString())
''# Initialize the Services that we're going to need now that we're
''# planning on hitting the database.
Dim RegionService As Domain.IRegionService = New Domain.RegionService(New Domain.RegionRepository)
''# Right now we're getting the requested region from the URI. This
''# is when a user requests something like
''# http://calgary.example.com, whereby we extract "calgary" out of
''# the address.
Dim region As Domain.Region = RegionService.GetRegionByName(url.Subdomain)
''# If the RegionService returned a region from it's query, then we
''# want to exit the method and allow the user to continue on using
''# this region.
If Not region Is Nothing Then
Return
End If
''# If we've made it this far, it means that the user either entered
''# an Invalid Region (yes, we already know the region is invalid) or
''# used www. or nothing as a subdomain. Up until this point, we
''# haven't cared if the user is authenticated or not, nor have we
''# cared what the full address in their address bar is. Now we're
''# probably going to start redirecting them somewhere.
''# First off we need to check if they're authenticated users. If they
''# are, we'll just send them on over to their default region.
If filterContext.HttpContext.User.Identity.IsAuthenticated Then
Dim userService As New Domain.UserService(New Domain.UserRepository)
Dim userRegion = userService.GetUserByID(AuthenticationHelper.RetrieveAuthUser.ID).Region.Name
filterContext.HttpContext.Response.Redirect(url.Scheme + "://" + userRegion + "." + url.PrimaryDomain + newPort + request.RawUrl)
End If
''# Now we know that the user is not Authenticated. So here we check for
''# www. If the host has www in it, then we just strip the www and
''# bounce the user to the original request.
If request.Url.Host.StartsWith("www") Then
Dim newUrl As String = url.Scheme + "://" + url.Host.Replace("www.", "") + newPort + request.RawUrl
''# The redirect is permanent because we NEVER want to see www in the domain.
filterContext.HttpContext.Response.RedirectPermanent(newUrl)
''# It's ok for an annonymous browser to view the "Details" of an
''# Event/User/Badge/Tag without being assigned to a regions. So
''# this is why we strip the www but don't redirect the visitor
''# directly over to the "Choose Your Region" view.
End If
''# If we've gone this far, we know the region is invalid, and the
''# user needs to be directed to a "choose your region" page. We're
''# not going to do the redirecting here because we want to allow for
''# browsing to specific Users/Tags/Badges/Events that are Region
''# Agnostic. But if a user tries to view an event listing of any
''# sort, we're going to fire them over to the "Choose Your Region"
''# page via a separate Attribute attached to only the Actions that
''# require it.
End Sub
Here's an uncommented C# version:
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var request = filterContext.HttpContext.Request;
Uri url = request.Url;
Uri referrer = (request.UrlReferrer != null) ? request.UrlReferrer : null;
if (((referrer != null)) && (!string.IsNullOrEmpty(url.Subdomain)) && (!(url.Subdomain == "www")) && (referrer.Host == url.Host)) {
return;
}
string newPort = url.IsDefaultPort ? string.Empty : ":" + url.Port.ToString();
Domain.IRegionService RegionService = new Domain.RegionService(new Domain.RegionRepository());
Domain.Region region = RegionService.GetRegionByName(url.Subdomain);
if ((region != null)) {
return;
}
if (filterContext.HttpContext.User.Identity.IsAuthenticated) {
Domain.UserService userService = new Domain.UserService(new Domain.UserRepository());
dynamic userRegion = userService.GetUserByID(AuthenticationHelper.RetrieveAuthUser.ID).Region.Name;
filterContext.HttpContext.Response.Redirect(url.Scheme + "://" + userRegion + "." + url.PrimaryDomain + newPort + request.RawUrl);
}
if (request.Url.Host.StartsWith("www")) {
string newUrl = url.Scheme + "://" + url.Host.Replace("www.", "") + newPort + request.RawUrl;
//'# The redirect is permanent because we NEVER want to see www in the domain.
filterContext.HttpContext.Response.RedirectPermanent(newUrl);
}
}