Как реализовать HttpMessageHandler в веб-API?
В проекте ASP.NET 4.5 MVC 4 Web API я хочу добавить пользовательский HttpMessageHandler
. Я изменил класс WebApiConfig
(в\App_Satrt\WebApiConfig.cs) следующим образом:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: null,
handler: new MyCustomizedHttpMessageHandler()
);
}
}
Затем я разработал MyCustomizedHttpMessageHandler
:
public class MyCustomizedHttpMessageHandler : HttpMessageHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
IPrincipal principal = new GenericPrincipal(
new GenericIdentity("myuser"), new string[] { "myrole" });
Thread.CurrentPrincipal = principal;
HttpContext.Current.User = principal;
return Task<HttpResponseMessage>.Factory.StartNew(() => request.CreateResponse());
}
}
Однако запрос API (скажем http://mylocalhost.com/api/values) всегда возвращает код состояния 200 без каких-либо данных. Я имею в виду, что он никогда не попадает в метод ValuesController.cs GET().
Что я пропустил? Как я могу правильно реализовать HttpMessageHandler
?
PS: Я уже прочитал это: qaru.site/info/114613/..., не помогает мне.
Ответы
Ответ 1
Здесь вы создаете HttpMessageHandler
, который замыкает запрос и не пропускает запрос через остальную часть конвейера. Вместо этого вы должны создать DelegatingHandler
.
Также есть два типа конвейеров обработчиков сообщений в Web API. Один из них является регулярным конвейером, в котором все запросы для всех маршрутов проходят через и другие, где могут быть обработчики сообщений, специфичные только для определенных маршрутов.
-
Попробуйте создать DelegatingHandler
и добавьте его в список обработчиков сообщений HttpConfiguration
:
config.MessageHandlers.Add(new HandlerA())
-
Если вы хотите добавить обработчик сообщений, специфичных для маршрута, вы можете сделать следующее:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: null,
handler:
HttpClientFactory.CreatePipeline(
new HttpControllerDispatcher(config),
new DelegatingHandler[]{new HandlerA()})
);
Этот веб-сайт Api показывает поток трубопровода.
Ответ 2
Чтобы написать собственный обработчик сообщений, вы должны получить от System.Net.Http.DelegatingHandler
class CustomMessageHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage>
SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
IPrincipal principal = new GenericPrincipal(
new GenericIdentity("myuser"), new string[] { "myrole" });
Thread.CurrentPrincipal = principal;
HttpContext.Current.User = principal;
return base.SendAsync(request, cancellationToken);
}
}
И вызовите base.SendAsync
, чтобы отправить запрос внутреннему обработчику.