你说的很对。自宿主返回 IHttpRoute 并以 HttpMessageHandler 作为参数。似乎没有内置方法来指定路由处理程序。
更新:更清楚一点
几乎可以肯定,您应该尝试使用 HttpControllerSelector 并实现自定义的...一个例子。 http://netmvc.blogspot.co.uk/
接下来是一些实验,如果 HttpControllerSelector 不能满足您的要求,无论出于何种原因...
但是,正如您所看到的,MapHttpRoute 确实对HttpMessageHandler 有重载,因此您可以对此进行试验...if the handler is NULL then it defaults to IHttpController 但您可以实现自己的并使用它来指向正确的控制器。 . MVC 框架似乎使用了[HttpControllerDispatcher]here,所以借用一些代码你也可以在这里放置你自己的控制器/路由选择代码——你可以访问路由和选择器,并且可以自己交换进出。
此 CustomHttpControllerDispatcher 代码仅用于 DEMO...查找行
//在这里做一些自定义来选择你的控制器
也许可以玩一下……
示例路线:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: null,
handler: new CustomHttpControllerDispatcher(config)
);
CustomHttpControllerDispatcher 示例:
public class CustomHttpControllerDispatcher : HttpMessageHandler
{
private IHttpControllerSelector _controllerSelector;
private readonly HttpConfiguration _configuration;
public CustomHttpControllerDispatcher(HttpConfiguration configuration)
{
_configuration = configuration;
}
public HttpConfiguration Configuration
{
get { return _configuration; }
}
private IHttpControllerSelector ControllerSelector
{
get
{
if (_controllerSelector == null)
{
_controllerSelector = _configuration.Services.GetHttpControllerSelector();
}
return _controllerSelector;
}
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return SendAsyncInternal(request, cancellationToken);
}
private Task<HttpResponseMessage> SendAsyncInternal(HttpRequestMessage request, CancellationToken cancellationToken)
{
IHttpRouteData routeData = request.GetRouteData();
Contract.Assert(routeData != null);
//DO SOMETHING CUSTOM HERE TO PICK YOUR CONTROLLER
HttpControllerDescriptor httpControllerDescriptor = ControllerSelector.SelectController(request);
IHttpController httpController = httpControllerDescriptor.CreateController(request);
// Create context
HttpControllerContext controllerContext = new HttpControllerContext(_configuration, routeData, request);
controllerContext.Controller = httpController;
controllerContext.ControllerDescriptor = httpControllerDescriptor;
return httpController.ExecuteAsync(controllerContext, cancellationToken);
}
}