Skip to content

Instantly share code, notes, and snippets.

@mikeobrien
Created October 20, 2011 15:45
Show Gist options
  • Save mikeobrien/1301469 to your computer and use it in GitHub Desktop.
Save mikeobrien/1301469 to your computer and use it in GitHub Desktop.
Regular Expression URL Policy
public class ConfigureFubuMVC : FubuRegistry
{
public ConfigureFubuMVC()
{
IncludeDiagnostics(true);
Actions.IncludeTypeNamesSuffixed("Command", "Query")
.IncludeMethodsPrefixed("Get", "Post");
Routes.HomeIs<DashboardQuery>(x => x.Get())
.ConstrainMethodPrefixToHttpGet("Get")
.ConstrainMethodPrefixToHttpPost("Post")
.UrlPolicy(RegExUrlPolicy.Create().
IgnoreNamespace<ConfigureFubuMVC>().
IgnoreClassName("Command", "Query").
IgnoreMethodName("Get", "Post"));
Media.ApplyContentNegotiationToActions(x => x.OutputType() == typeof(AjaxResponse));
Policies.WrapBehaviorChainsWith<AuthorizationBehavior>()
.ConditionallyWrapBehaviorChainsWith<ExceptionHandlerBehavior>(x => !debug);
this.UseSpark();
HtmlConvention<HtmlConventions>();
Views.TryToAttach(x => x.by_ViewModel_and_Namespace());
}
}
public class RegExUrlPolicy : IUrlPolicy
{
private readonly Func<ActionCall, bool> _matchFilter;
private readonly List<string> _namespacePatterns = new List<string>();
private readonly List<string> _classPatterns = new List<string>();
private readonly List<string> _methodPatterns = new List<string>();
private bool _ignoreNamespace;
private bool _ignoreClass;
private bool _ignoreMethod;
public RegExUrlPolicy(Func<ActionCall, bool> matchFilter)
{
_matchFilter = matchFilter;
}
public static RegExUrlPolicy Create()
{
return new RegExUrlPolicy(x => true);
}
public static RegExUrlPolicy Create(Func<ActionCall, bool> matchFilter)
{
return new RegExUrlPolicy(matchFilter);
}
public bool Matches(ActionCall call, IConfigurationObserver log)
{
return _matchFilter(call);
}
public RegExUrlPolicy IgnoreNamespace<T>()
{
_namespacePatterns.Add(typeof(T).Namespace);
return this;
}
public RegExUrlPolicy IgnoreNamespace(params string[] patterns)
{
_ignoreNamespace = !patterns.Any();
_namespacePatterns.AddRange(patterns);
return this;
}
public RegExUrlPolicy IgnoreClassName(params string[] patterns)
{
_ignoreClass = !patterns.Any();
_classPatterns.AddRange(patterns);
return this;
}
public RegExUrlPolicy IgnoreMethodName(params string[] patterns)
{
_ignoreMethod = !patterns.Any();
_methodPatterns.AddRange(patterns);
return this;
}
public IRouteDefinition Build(ActionCall call)
{
var route = call.ToRouteDefinition();
if (!_ignoreNamespace) AppendNamespace(route, call, _namespacePatterns);
if (!_ignoreClass) AppendClass(route, call, _classPatterns);
if (!_ignoreMethod) AppendMethod(route, call, _methodPatterns);
return route;
}
private static void AppendNamespace(IRouteDefinition route, ActionCall call, IEnumerable<string> ignore)
{
route.Append(RemovePattern(call.HandlerType.Namespace, ignore).Replace('.', '/').ToLower());
}
private static void AppendClass(IRouteDefinition route, ActionCall call, IEnumerable<string> ignore)
{
route.Append(RemovePattern(call.HandlerType.Name, ignore).ToLower());
}
private static void AppendMethod(IRouteDefinition route, ActionCall call, IEnumerable<string> ignore)
{
var methodName = RemovePattern(call.Method.Name, ignore);
if (MethodToUrlBuilder.Matches(call.Method.Name) && call.HasInput)
{
MethodToUrlBuilder.Alter(route, methodName, new TypeDescriptorCache().GetPropertiesFor(call.InputType()).Keys, x => { });
route.ApplyInputType(call.InputType());
}
else if (!string.IsNullOrEmpty(methodName)) route.Append(methodName.ToLower());
}
private static string RemovePattern(string source, IEnumerable<string> pattern)
{
return pattern.Aggregate(source, (a, i) => new Regex(i).Replace(a, string.Empty));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment