You can assign a message handler to a route for a route that should use the selection logic of another controller. This handler will flag the HttpRequestMessage flag so that this request is handled differently.
Then just draw a CustomControllerSelector inheritance from DefaultHttpControllerSelector and check this flag:
- if installed, continue your own logic
- if it is not installed, return to the database (
DefaultHttpControllerSelector )
Here is the code:
1) by setting the flag
public class RouteSpecificHandler : DelegatingHandler { protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { request.Properties["UseCustomSelector"] = true; return base.SendAsync(request, cancellationToken); } }
2) assignment of a message handler only to a specific route (do not start for other routes)
config.Routes.MapHttpRoute( name: "MyRoute", routeTemplate: "api/dummy/{id}", defaults: new {controller = "Dummy", id = RouteParameter.Optional}, constraints: null, handler: new RouteSpecificHandler { InnerHandler = new HttpControllerDispatcher(config) } );
3) custom selector observing flag:
public class CustomSelector : DefaultHttpControllerSelector { public CustomSelector(HttpConfiguration configuration) : base(configuration) { } public override HttpControllerDescriptor SelectController(HttpRequestMessage request) { if (request.Properties.ContainsKey("UseCustomSelector") && request.Properties["UseCustomSelector"] as bool? == true) {
4) registration of the selector:
config.Services.Replace(typeof(IHttpControllerSelector), new CustomSelector(config));
Edit
If you do not want to inherit from DefaultHttpControllerSelector , then implement IHttpControllerSelector directly, and instead of calling base.SelectController(request) save the old selector as a field / class property in your class
public class CustomSelector : IHttpControllerSelector { private HttpConfiguration _config; public IHttpControllerSelector PreviousSelector {get; set;} public CustomSelector(HttpConfiguration configuration) { _config = configuration; } public override HttpControllerDescriptor SelectController(HttpRequestMessage request) { if (request.Properties.ContainsKey("UseCustomSelector") && request.Properties["UseCustomSelector"] as bool? == true) {
Then just change the registration:
var previousSelector = config.Services.GetService(typeof(IHttpControllerSelector)) as IHttpControllerSelector; config.Services.Replace(typeof(IHttpControllerSelector), new CustomSelector(config) { PreviousSelector = previousSelector});