我一直在尝试学习不同的编程模式,而“责任链”则是我无法理解的。有人告诉我,我的特定代码片段将是一个很好的责任链候选人,我想知道是否有人能告诉我如何到达那里?
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下面是一个未注释的C#版本:
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);
}
}发布于 2011-08-20 15:21:07
这种方法不适合于责任链模式,但肯定可以使用它来实现(仅仅为了教育目的):
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//Init
var referrerRequestHandler = new ReferrerRequestHandler();
var regionRequestHandler = new RegionRequestHandler();
var authenticatedRequestHandler = new AuthenticatedRequestHandler(filterContext);
var wwwRequestHandler = new WwwRequestHandler(filterContext);
referrerRequestHandler.SetNextHandler(regionRequestHandler);
regionRequestHandler.SetNextHandler(authenticatedRequestHandler);
authenticatedRequestHandler.SetNextHandler(wwwRequestHandler);
//Run
var request = filterContext.HttpContext.Request;
referrerRequestHandler.Redirect(request);
} public abstract class RequestHandler
{
public void SetNextHandler(RequestHandler nextHandler)
{
_nextHandler = nextHandler;
}
public void Redirect(HttpRequestBase request)
{
bool handeled = HandleRedirect(request);
if (!handeled)
{
if (_nextHandler != null)
{
_nextHandler.Redirect(request);
}
}
}
protected abstract bool HandleRedirect(HttpRequestBase request);
private RequestHandler _nextHandler;
} public class ReferrerRequestHandler : RequestHandler
{
protected override bool HandleRedirect(HttpRequestBase 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 true;
}
else
{
return false;
}
}
} public class RegionRequestHandler: RequestHandler
{
protected override bool HandleRedirect(HttpRequestBase request)
{
Domain.IRegionService RegionService = new Domain.RegionService(new Domain.RegionRepository());
Domain.Region region = RegionService.GetRegionByName(url.Subdomain);
if ((region != null))
{
return true;
}
else
{
return false;
}
}
} public class AuthenticatedRequestHandler: RequestHandler
{
public AuthenticatedRequestHandler(ActionExecutingContext filterContext)
{
_filterContext = filterContext;
}
protected override bool HandleRedirect(HttpRequestBase request)
{
Uri url = request.Url;
string newPort = url.IsDefaultPort ? string.Empty : ":" + url.Port.ToString();
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);
return true;
}
else
{
return false;
}
}
private readonly ActionExecutingContext _filterContext;
} public class WwwRequestHandler : RequestHandler
{
public WwwRequestHandler(ActionExecutingContext filterContext)
{
_filterContext = filterContext;
}
protected override bool HandleRedirect(HttpRequestBase request)
{
Uri url = request.Url;
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);
return true;
}
else
{
return false;
}
}
private readonly ActionExecutingContext _filterContext;
}https://codereview.stackexchange.com/questions/4250
复制相似问题