Custom IHttpControllerSelector for ASP.NET Web Interface for Single Route

I need a custom IHttpControllerSelector , which should only apply to a specific route. All other api web routes should use the standard implementation of IHttpControllerSelector .

During the research, I found the following code intended to replace IHttpControllerSelector when the application starts, but completely replaces the default controller selector, which leads to the fact that all routes in the application use my custom controller selector:

 config.Services.Replace(typeof(IHttpControllerSelector), new CustomControllerSelector(config)); 

Is there a way to configure IHttpControllerSelector for a single route?

+4
source share
1 answer

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) { //your logic goes here } return base.SelectController(request); } } 

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) { //your logic goes here } return PreviousSelector.SelectController(request); } } 

Then just change the registration:

  var previousSelector = config.Services.GetService(typeof(IHttpControllerSelector)) as IHttpControllerSelector; config.Services.Replace(typeof(IHttpControllerSelector), new CustomSelector(config) { PreviousSelector = previousSelector}); 
+8
source

Source: https://habr.com/ru/post/1204600/


All Articles