Подтвердить что ты не робот

Пользовательские обработчики маршрутов в ASP.Net WebAPI

Я могу успешно зарегистрировать собственный обработчик маршрута (исходящий из IRouteHandler) внутри global.asax.cs для маршрута веб-API ala:

        routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "{client}/api/1.0/{controller}/{action}/{id}",
            defaults: new{id = UrlParameter.Optional}
        ).RouteHandler = new SingleActionAPIRouteHandler();

Однако я не могу найти способ сделать это, пытаясь настроить хост памяти для API для тестирования интеграции, когда я вызываю HttpConfiguration.Routes.MapRoute. Я не могу установить обработчик на вернулся IHttpRoute.

Должен ли я делать это по-другому (например, используя пользовательский HttpControllerSelector)? Я бы хотел сделать это одинаково в обоих случаях.

Спасибо, Matt

EDIT:

Итак, что я в итоге сделал, в основном следуя советам ниже, но просто переопределяя класс HttpControllerDispatcher следующим образом:

public class CustomHttpControllerDispatcher : HttpControllerDispatcher
{
    public CustomHttpControllerDispatcher(HttpConfiguration configuration) : base(configuration)
    {
    }
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        // My stuff here

        return base.SendAsync(request, cancellationToken);
    }
}
4b9b3361

Ответ 1

Ты очень прав. Self host возвращает IHttpRoute и принимает параметр HttpMessageHandler в качестве параметра. Кажется, нет встроенного способа специфичности обработчика маршрута.

Обновление: быть немного понятным

Вам почти наверняка придется использовать HttpControllerSelector и реализовать пользовательский... Примером является. http://netmvc.blogspot.co.uk/

Далее следует немного экспериментов, если HttpControllerSelector недостаточно для ваших требований по какой-либо причине...

Но, поскольку вы можете видеть, что MapHttpRoute имеет перегрузку для HttpMessageHandler, поэтому вы можете поэкспериментировать с этим... если обработчик равен NULL то он по умолчанию используется для IHttpController, но вы можете реализовать свои собственные и использовать его для прямого управления с правильным контроллером... Структура MVC, как представляется, использует [HttpControllerDispatcher] здесь, поэтому, заимствуя некоторый код, вы также можете разместить свой собственный код выбора контроллера/маршрута - у вас есть доступ к маршруту и ​​селектору, и вы можете его самостоятельно менять.

Этот код 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);
        }
}