Revisions
-
IDisposable revised this gist
May 27, 2016 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -10,7 +10,7 @@ using System.Web.Mvc; using System.Web.Routing; namespace YourApplication { internal static class DomainRegexCache { -
IDisposable revised this gist
Nov 20, 2014 . 2 changed files with 193 additions and 19 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,21 +2,41 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Text.RegularExpressions; using System.Web; using System.Web.Http; using System.Web.Http.Routing; using System.Web.Mvc; using System.Web.Routing; namespace Alerts.Helpers { internal static class DomainRegexCache { // since we're often going to have the same pattern used in multiple routes, it's best to build just one regex per pattern private static ConcurrentDictionary<string, Regex> _domainRegexes = new ConcurrentDictionary<string, Regex>(); internal static Regex CreateDomainRegex(string domain) { return _domainRegexes.GetOrAdd(domain, (d) => { d = d.Replace("/", @"\/") .Replace(".", @"\.") .Replace("-", @"\-") .Replace("{", @"(?<") .Replace("}", @">(?:[a-zA-Z0-9_-]+))"); return new Regex("^" + d + "$", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture); }); } } public class DomainRoute : Route { private const string DomainRouteMatchKey = "DomainRoute.Match"; private const string DomainRouteInsertionsKey = "DomainRoute.Insertions"; private Regex _domainRegex; public string Domain { get; private set; } @@ -39,7 +59,7 @@ public DomainRoute(string domain, string url, RouteValueDictionary defaults, IRo : base(url, defaults, routeHandler) { Domain = domain; _domainRegex = DomainRegexCache.CreateDomainRegex(Domain); } public override RouteData GetRouteData(HttpContextBase httpContext) @@ -87,20 +107,6 @@ public override VirtualPathData GetVirtualPath(RequestContext requestContext, Ro return base.GetVirtualPath(requestContext, RemoveDomainTokens(requestContext, values)); } private RouteValueDictionary RemoveDomainTokens(RequestContext requestContext, RouteValueDictionary values) { var myInsertions = requestContext.HttpContext.Items[DomainRouteInsertionsKey] as HashSet<string>; @@ -118,6 +124,7 @@ private RouteValueDictionary RemoveDomainTokens(RequestContext requestContext, R } } // For MVC routes public class DomainRouteCollection { private string Domain { get; set; } @@ -156,6 +163,8 @@ public Route MapRoute(string name, string url, object defaults, string[] namespa public Route MapRoute(string name, string url, object defaults, object constraints, string[] namespaces) { if (name == null) throw new ArgumentNullException("name"); if (url == null) throw new ArgumentNullException("url"); @@ -174,6 +183,7 @@ public Route MapRoute(string name, string url, object defaults, object constrain } } // For Areas routes public class DomainAreaRegistrationContext { private AreaRegistrationContext Context { get; set; } @@ -226,4 +236,148 @@ public Route MapRoute(string name, string url, object defaults, object constrain return route; } } // WebApi Routes public class DomainHttpRoute : HttpRoute { private const string DomainRouteMatchKey = "DomainHttpRoute.Match"; private const string DomainRouteInsertionsKey = "DomainHttpRoute.Insertions"; private Regex _domainRegex; public string Domain { get; private set; } public DomainHttpRoute(string domain) : this(domain, (string)null, (HttpRouteValueDictionary)null, (HttpRouteValueDictionary)null, (HttpRouteValueDictionary)null, (HttpMessageHandler)null) { } public DomainHttpRoute(string domain, string routeTemplate) : this(domain, routeTemplate, (HttpRouteValueDictionary)null, (HttpRouteValueDictionary)null, (HttpRouteValueDictionary)null, (HttpMessageHandler)null) { } public DomainHttpRoute(string domain, string routeTemplate, HttpRouteValueDictionary defaults) : this(domain, routeTemplate, defaults, (HttpRouteValueDictionary)null, (HttpRouteValueDictionary)null, (HttpMessageHandler)null) { } public DomainHttpRoute(string domain, string routeTemplate, HttpRouteValueDictionary defaults, HttpRouteValueDictionary constraints) : this(domain, routeTemplate, defaults, constraints, (HttpRouteValueDictionary)null, (HttpMessageHandler)null) { } public DomainHttpRoute(string domain, string routeTemplate, HttpRouteValueDictionary defaults, HttpRouteValueDictionary constraints, HttpRouteValueDictionary dataTokens) : this(domain, routeTemplate, defaults, constraints, dataTokens, (HttpMessageHandler)null) { } public DomainHttpRoute(string domain, string routeTemplate, HttpRouteValueDictionary defaults, HttpRouteValueDictionary constraints, HttpRouteValueDictionary dataTokens, HttpMessageHandler handler) : base(routeTemplate, defaults, constraints, dataTokens, handler) { Domain = domain; _domainRegex = DomainRegexCache.CreateDomainRegex(Domain); } public override IHttpRouteData GetRouteData(string virtualPathRoot, HttpRequestMessage request) { var requestDomain = request.RequestUri.Host; var domainMatch = _domainRegex.Match(requestDomain); if (!domainMatch.Success) return null; object existingMatch; if (!request.Properties.TryGetValue(DomainRouteMatchKey, out existingMatch)) request.Properties[DomainRouteMatchKey] = Domain; else if (Domain != existingMatch as string) return null; var data = base.GetRouteData(virtualPathRoot, request); if (data == null) return null; var myInsertions = new HashSet<string>(); for (var i = 1; i < domainMatch.Groups.Count; i++) { var group = domainMatch.Groups[i]; if (group.Success) { var key = _domainRegex.GroupNameFromNumber(i); if (!String.IsNullOrEmpty(key) && !String.IsNullOrEmpty(group.Value)) { // could throw here if data.Values.ContainsKey(key) if we wanted to prevent multiple matches data.Values[key] = group.Value; myInsertions.Add(key); } } } request.Properties[DomainRouteInsertionsKey] = myInsertions; return data; } public override IHttpVirtualPathData GetVirtualPath(HttpRequestMessage request, IDictionary<string, object> values) { return base.GetVirtualPath(request, RemoveDomainTokens(request, values)); } private IDictionary<string, object> RemoveDomainTokens(HttpRequestMessage request, IDictionary<string, object> values) { var myInsertions = request.Properties[DomainRouteInsertionsKey] as HashSet<string>; if (myInsertions != null) { foreach (var key in myInsertions) { if (values.ContainsKey(key)) values.Remove(key); } } return values; } } // for WebApi routes public class DomainHttpRouteCollection { private string Domain { get; set; } private HttpRouteCollection Routes { get; set; } public DomainHttpRouteCollection(string domain, HttpRouteCollection routes) { Domain = domain; Routes = routes; } public IHttpRoute MapDomainHttpRoute(string name, string routeTemplate) { return MapDomainHttpRoute(name, routeTemplate, null, null, null); } public IHttpRoute MapDomainHttpRoute(string name, string routeTemplate, object defaults) { return MapDomainHttpRoute(name, routeTemplate, defaults, null, null); } public IHttpRoute MapDomainHttpRoute(string name, string routeTemplate, object defaults, object constraints) { return MapDomainHttpRoute(name, routeTemplate, defaults, constraints, null); } public IHttpRoute MapDomainHttpRoute(string name, string routeTemplate, object defaults, object constraints, HttpMessageHandler handler) { if (name == null) throw new ArgumentNullException("name"); if (routeTemplate == null) throw new ArgumentNullException("routeTemplate"); var route = new DomainHttpRoute(Domain, routeTemplate, new HttpRouteValueDictionary(defaults), new HttpRouteValueDictionary(constraints)); Routes.Add(name, route); return route; } } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,20 @@ using System.Web.Http; using System.Web.Http.ExceptionHandling; using System.Web.Http.ModelBinding; using YourApi; namespace YourApi { public static class WebApiConfig { public static void Register(HttpConfiguration config) { var clientApiRoutes = new DomainHttpRouteCollection("{clientHost}" + MvcApplication.ClientSuffix, config.Routes); clientApiRoutes.MapDomainHttpRoute( name: "DefaultApi", routeTemplate: "api/v1/{controller}/{action}" ); } } } -
IDisposable revised this gist
Nov 19, 2014 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -95,7 +95,7 @@ private static Regex CreateDomainRegex(string domain) .Replace(".", @"\.") .Replace("-", @"\-") .Replace("{", @"(?<") .Replace("}", @">(?:[a-zA-Z0-9_-]+))"); return new Regex("^" + d + "$", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture); }); -
IDisposable revised this gist
Nov 19, 2014 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,7 +1,7 @@ using System.Web.Mvc; using YourApplication; namespace YourApplication.Areas.Login { public class LoginAreaRegistration : AreaRegistration { -
IDisposable created this gist
Nov 19, 2014 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,229 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using System.Web; using System.Web.Mvc; using System.Web.Routing; namespace Alerts.Helpers { public class DomainRoute : Route { private const string DomainRouteMatchKey = "DomainRoute.Match"; private const string DomainRouteInsertionsKey = "DomainRoute.Insertions"; // since we're often going to have the same pattern used in multiple routes, it's best to build just one regex per pattern private static ConcurrentDictionary<string, Regex> _domainRegexes = new ConcurrentDictionary<string, Regex>(); private Regex _domainRegex; public string Domain { get; private set; } public DomainRoute(string domain, string url, RouteValueDictionary defaults) : this(domain, url, defaults, new MvcRouteHandler()) { } public DomainRoute(string domain, string url, object defaults) : this(domain, url, new RouteValueDictionary(defaults), new MvcRouteHandler()) { } public DomainRoute(string domain, string url, object defaults, IRouteHandler routeHandler) : this(domain, url, new RouteValueDictionary(defaults), routeHandler) { } public DomainRoute(string domain, string url, RouteValueDictionary defaults, IRouteHandler routeHandler) : base(url, defaults, routeHandler) { Domain = domain; _domainRegex = CreateDomainRegex(Domain); } public override RouteData GetRouteData(HttpContextBase httpContext) { var requestDomain = httpContext.Request.Url.Host; var domainMatch = _domainRegex.Match(requestDomain); if (!domainMatch.Success) return null; var existingMatch = httpContext.Items[DomainRouteMatchKey] as string; if (existingMatch == null) httpContext.Items[DomainRouteMatchKey] = Domain; else if (existingMatch != Domain) return null; var data = base.GetRouteData(httpContext); if (data == null) return null; var myInsertions = new HashSet<string>(); for (var i = 1; i < domainMatch.Groups.Count; i++) { var group = domainMatch.Groups[i]; if (group.Success) { var key = _domainRegex.GroupNameFromNumber(i); if (!String.IsNullOrEmpty(key) && !String.IsNullOrEmpty(group.Value)) { // could throw here if data.Values.ContainsKey(key) if we wanted to prevent multiple matches data.Values[key] = group.Value; myInsertions.Add(key); } } } httpContext.Items[DomainRouteInsertionsKey] = myInsertions; return data; } public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) { return base.GetVirtualPath(requestContext, RemoveDomainTokens(requestContext, values)); } private static Regex CreateDomainRegex(string domain) { return _domainRegexes.GetOrAdd(domain, (d) => { d = d.Replace("/", @"\/") .Replace(".", @"\.") .Replace("-", @"\-") .Replace("{", @"(?<") .Replace("}", @">(?:[a-zA-Z0-9_-]*))"); return new Regex("^" + d + "$", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture); }); } private RouteValueDictionary RemoveDomainTokens(RequestContext requestContext, RouteValueDictionary values) { var myInsertions = requestContext.HttpContext.Items[DomainRouteInsertionsKey] as HashSet<string>; if (myInsertions != null) { foreach (var key in myInsertions) { if (values.ContainsKey(key)) values.Remove(key); } } return values; } } public class DomainRouteCollection { private string Domain { get; set; } private RouteCollection Routes { get; set; } public DomainRouteCollection(string domain, RouteCollection routes) { Domain = domain; Routes = routes; } public Route MapRoute(string name, string url) { return MapRoute(name, url, null, null, null); } public Route MapRoute(string name, string url, object defaults) { return MapRoute(name, url, defaults, null, null); } public Route MapRoute(string name, string url, string[] namespaces) { return MapRoute(name, url, null, null, namespaces); } public Route MapRoute(string name, string url, object defaults, object constraints) { return MapRoute(name, url, defaults, constraints, null); } public Route MapRoute(string name, string url, object defaults, string[] namespaces) { return MapRoute(name, url, defaults, null, namespaces); } public Route MapRoute(string name, string url, object defaults, object constraints, string[] namespaces) { if (url == null) throw new ArgumentNullException("url"); var route = new DomainRoute(Domain, url, defaults, new MvcRouteHandler()) { Constraints = new RouteValueDictionary(constraints), DataTokens = new RouteValueDictionary() }; if (namespaces != null && namespaces.Length > 0) route.DataTokens["Namespaces"] = namespaces; Routes.Add(name, route); return route; } } public class DomainAreaRegistrationContext { private AreaRegistrationContext Context { get; set; } private DomainRouteCollection Routes { get; set; } public DomainAreaRegistrationContext(string domain, AreaRegistrationContext context) { Context = context; Routes = new DomainRouteCollection(domain, Context.Routes); } public Route MapRoute(string name, string url) { return MapRoute(name, url, null, null, null); } public Route MapRoute(string name, string url, object defaults) { return MapRoute(name, url, defaults, null, null); } public Route MapRoute(string name, string url, string[] namespaces) { return MapRoute(name, url, null, null, namespaces); } public Route MapRoute(string name, string url, object defaults, object constraints) { return MapRoute(name, url, defaults, constraints, null); } public Route MapRoute(string name, string url, object defaults, string[] namespaces) { return MapRoute(name, url, defaults, null, namespaces); } public Route MapRoute(string name, string url, object defaults, object constraints, string[] namespaces) { if (namespaces == null && Context.Namespaces != null) namespaces = Context.Namespaces.ToArray(); var route = Routes.MapRoute(name, url, defaults, constraints, namespaces); route.DataTokens["area"] = Context.AreaName; // disabling the namespace lookup fallback mechanism keeps this area from accidentally picking up // controllers belonging to other areas bool useNamespaceFallback = (namespaces == null || namespaces.Length == 0); route.DataTokens["UseNamespaceFallback"] = useNamespaceFallback; return route; } } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,27 @@ using System.Web.Mvc; using Alerts.Helpers; namespace Alerts.Admin.Areas.Login { public class LoginAreaRegistration : AreaRegistration { public override string AreaName { get { return "Login"; } } public override void RegisterArea(AreaRegistrationContext context) { var loginAreaContext = new DomainAreaRegistrationContext("login" + MvcApplication.DnsSuffix, context); loginAreaContext.MapRoute( name: "Login", url: "", defaults: new { controller = "Login", action = "Login", id = UrlParameter.Optional } ); } } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,30 @@ using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; namespace YourApplication { public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); var clientRoutes = new DomainRouteCollection("{clientHost}" + MvcApplication.DnsSuffix, routes); RegisterRootRoutes(clientRoutes); } private static void RegisterRootRoutes(DomainRouteCollection routes) { routes.MapRoute( name: "Root/Index", url: "", defaults: new { controller = "Root", action = "Index" } ); } } }