Skip to content

Instantly share code, notes, and snippets.

@JeffreyZhao
Created August 24, 2009 10:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JeffreyZhao/173811 to your computer and use it in GitHub Desktop.
Save JeffreyZhao/173811 to your computer and use it in GitHub Desktop.
DomainParser
internal class DomainParser
{
public DomainParser(string pattern)
{
this.Pattern = pattern;
this.Segments = CaptureSegments(pattern);
string routePattern = pattern.Replace("://", "/").Replace('.', '/');
this.m_parsedRoute = RouteParser.Parse(routePattern);
}
private static ReadOnlyCollection<string> CaptureSegments(string domainPattern)
{
var regex = @"{\*?([^}]+)}";
var matches = Regex.Matches(domainPattern, regex).Cast<Match>();
var segments = matches.Select(m => m.Groups[1].Value);
return new ReadOnlyCollection<string>(segments.ToList());
}
public ReadOnlyCollection<string> Segments { get; private set; }
public string Pattern { get; private set; }
public RouteValueDictionary Match(Uri uri)
{
var toParse = ConvertDomainToPath(uri);
var domainValues = this.m_parsedRoute.Match(toParse, null);
if (domainValues == null) return null;
var result = new RouteValueDictionary();
foreach (var pair in domainValues)
{
var value = pair.Value as string;
if (value != null)
{
result.Add(pair.Key, value.Replace('/', '.'));
}
else
{
result.Add(pair.Key, pair.Value);
}
}
return result;
}
public string Bind(RouteValueDictionary currentValues, RouteValueDictionary values)
{
currentValues = currentValues ?? new RouteValueDictionary();
values = values ?? new RouteValueDictionary();
var acceptValues = new RouteValueDictionary();
foreach (var name in this.Segments)
{
object segmentValue;
if (values.TryGetValue(name, out segmentValue) ||
currentValues.TryGetValue(name, out segmentValue))
{
acceptValues.Add(name, segmentValue);
}
else
{
return null;
}
}
var boundUrl = this.m_parsedRoute.Bind(null, acceptValues, null, null);
if (boundUrl == null) return null;
return ConvertPathToDomain(boundUrl.Url);
}
private static string ConvertPathToDomain(string url)
{
var domainParts = url.Split('/');
var domain = domainParts[0];
for (int i = 1; i < domainParts.Length; i++)
{
domain += (i == 1 ? "://" : ".");
domain += domainParts[i];
}
return domain;
}
private static string ConvertDomainToPath(Uri uri)
{
return uri.Scheme + "/" + uri.Host.Replace('.', '/');
}
private ParsedRoute m_parsedRoute;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment