18

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、役に立ちません。

4

3 に答える 3

24

ここでは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 ポスターは、パイプライン フローを示しています。

于 2013-03-04T17:25:36.693 に答える
14

カスタム メッセージ ハンドラーを作成するには、次から派生する必要があります。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そして、リクエストを内部ハンドラに送信するために呼び出します。

于 2013-03-04T15:02:19.693 に答える
0

問題を解決するために@cuongleの回答を使用しました。1つ追加するだけです。そのため、「The inner handler has not been assigned.」を取得できませんでした。ありがとうございます。

public class CustomMessageHandler : DelegatingHandler
{
        public CustomMessageHandler ()
        {
              //add this to solve "The inner handler has not been assigned"
               InnerHandler = new HttpClientHandler();
        }
    
        protected override async Task<HttpResponseMessage> 
          SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            // Before request 
            IPrincipal principal = new GenericPrincipal(
                new GenericIdentity("myuser"), new string[] { "myrole" });
            Thread.CurrentPrincipal = principal;
            HttpContext.Current.User = principal;
    
            var result = await base.SendAsync(request, cancellationToken);
    
            // After request when response arrives
            
            return result;
        }
}
于 2020-12-20T12:59:25.093 に答える