Skip to content

Instantly share code, notes, and snippets.

@agc93
Created August 2, 2017 06:28
Show Gist options
  • Save agc93/473fa9441cfde4276b7ec658edb97437 to your computer and use it in GitHub Desktop.
Save agc93/473fa9441cfde4276b7ec658edb97437 to your computer and use it in GitHub Desktop.
Runtime route prefixing
[Route("{prefix?}")]
public class ApiController : Controller {}
public class RouteActionConstraint : IActionConstraint, IActionConstraintMetadata
{
private readonly ILogger _logger;
public string Prefix { get; private set; }
internal RouteActionConstraint(string prefix, ILogger logger) {
Prefix = prefix;
_logger = logger;
}
public int Order => 0;
public bool Accept(ActionConstraintContext context)
{
_logger.LogDebug("Matching route using prefix: {0}", Prefix ?? string.Empty);
return string.IsNullOrWhiteSpace(Prefix)
? true
: context.RouteContext.RouteData.Values.First().Value?.ToString() == Prefix;
// this is specifically for prefix, and would need to be improved for other routing scenarious
}
}
public class PrefixRouteConvention : IActionModelConvention
{
private readonly string _prefix;
private readonly ILoggerFactory _factory;
public DownlinkRouteConvention(IConfiguration config, ILoggerFactory factory) {
_prefix = config.GetValue("RoutePrefix", string.Empty);
_factory = factory;
}
public void Apply(ActionModel action)
{
if (action.Controller.ControllerType == typeof(Controllers.ApiController)) { // restrict to this controller
foreach(var selector in action.Selectors) {
selector.ActionConstraints.Add(
new RouteActionConstraint(
_prefix,
_factory.CreateLogger(nameof(RouteActionConstraint))));
}
}
}
}
services.AddSingleton<PrefixRouteConvention>();
services.Configure<MvcOptions>(opts => opts.Conventions.Add(services.BuildServiceProvider().GetService<PrefixRouteConvention>()));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment