web-dev-qa-db-ja.com

Web APIにHttpMessageHandlerを実装する方法は?

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:これはすでに読んだことがあります: https://stackoverflow.com/a/12030785/538387 、私を助けません。

16
Tohid

ここでは、リクエストを短絡し、リクエストが残りのパイプラインを通過しないようにするHttpMessageHandlerを作成しています。代わりに、DelegatingHandlerを作成する必要があります。

また、Web APIには2種類のメッセージハンドラパイプラインがあります。 1つは、すべてのルートのすべてのリクエストが通過する通常のパイプラインであり、もう1つは、特定のルートにのみ固有のメッセージハンドラーを持つことができるパイプラインです。

  1. DelegatingHandlerを作成して、HttpConfigurationのメッセージハンドラーのリストに追加してください。

    config.MessageHandlers.Add(new HandlerA())
    
  2. ルート固有のメッセージハンドラーを追加する場合は、次のようにします。

    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()})
                );
    

このWeb APIポスター は、パイプラインのフローを示しています。

23
Kiran Challa

カスタムメッセージハンドラーを作成するには、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を呼び出して、リクエストを内部ハンドラーに送信します。

11
cuongle