2013-03-04 13 views
16

W projekcie ASP.NET 4.5 MVC 4 Web API chcę dodać niestandardowy HttpMessageHandler. Zmieniłem WebApiConfig klasę (w \ App_Satrt \ WebApiConfig.cs), w następujący sposób:Jak zaimplementować HttpMessageHandler w Web API?

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

Potem rozwinął 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()); 
    } 
} 

Jednakże wniosek do API (powiedzmy http://mylocalhost.com/api/values) , zawsze zwraca kod stanu 200, bez żadnych danych. Mam na myśli, że nigdy nie dostaje się do metody "GET()" ValuesController.cs.

Co przeoczyłem? Jak mogę poprawnie wdrożyć HttpMessageHandler?

PS: Przeczytałem już: https://stackoverflow.com/a/12030785/538387, nie pomaga mi.

Odpowiedz

22

Tutaj tworzysz HttpMessageHandler, który powoduje zwarcie żądania i nie pozwala, aby żądanie przechodziło przez resztę potoku. Zamiast tego powinieneś utworzyć DelegatingHandler.

Istnieją również dwa rodzaje potoków obsługi komunikatów w interfejsie API sieci Web. Jednym z nich jest regularny potok, w którym przechodzą wszystkie żądania wszystkich tras i inne, w których można obsługiwać komunikatory tylko dla określonych tras.

  1. próby utworzenia DelegatingHandler i dodać go do listy Twoich HttpConfiguration „s koparki wiadomość:

    config.MessageHandlers.Add(new HandlerA()) 
    
  2. Jeśli chcesz dodać do obsługi konkretnej wiadomości trasy, a następnie można wykonać następujące czynności :

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

This Web Api Poster pokazuje PIPELI ne przepływ.

+0

Dziękuję. Rozwiązanie (1) działa dobrze. Ale numer 2, 'new HttpControllerDispatcher()' mówi: ** System.Web.Http.Dispatcher.HttpControllerDispatcher nie zawiera konstruktora, który przyjmuje 0 argumentów ** - Aktualizacja: Poprawiłem twój kod. Dziękuję Ci. – Tohid

+0

zaktualizowałem mój powyższy post too.thanks. –

+0

Należy również dodać tę część odpowiedzi Cuong Le do odpowiedzi: ** Aby napisać niestandardową procedurę obsługi komunikatów, należy wyprowadzić z 'System.Net.Http.DelegatingHandler'. ** – Tohid

11

Aby napisać klasę obsługi wiadomości, należy czerpać z 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); 
    } 
} 

I zadzwonić base.SendAsync wysłać żądanie do wewnętrznej obsługi.

+2

@Cuonge Le - Dziękujemy za odpowiedź. Po tym, jak zastąpiłem 'CustomMessageHandler' twoim kodem, podnosi on błąd na' return base.SendAsync (request, cancellationToken); 'saying: ** Wewnętrzny handler nie został przypisany. **. Co znowu przegapiłem? – Tohid

+0

@Counge Le - Połączenie twojej odpowiedzi i Kirran Challa rozwiązało problem. Jeszcze raz dziękuję. – Tohid

+0

@Cuong Le jaki jest odpowiednik dla .NET 4.0? Nie mogłem znaleźć DelegatingHandler dla .NET .4 ... jak można obsługiwać wiadomości w wersji 4.0. Dzięki za pomoc. – jaxxbo