2013-03-04 11 views
16

In un progetto API Web MVC 4 ASP.NET 4.5, desidero aggiungere un numero personalizzato HttpMessageHandler. Ho cambiato WebApiConfig classe (in \ App_Satrt \ WebApiConfig.cs), come segue:Come implementare HttpMessageHandler nell'API Web?

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

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

Tuttavia, la richiesta alle API (diciamo http://mylocalhost.com/api/values) , restituisce sempre il codice di stato 200, senza dati. Voglio dire che non arriva mai al metodo 'GET()' di ValuesController.cs.

Cosa mi è mancato? Come posso implementare correttamente HttpMessageHandler?

PS: Ho già letto questo: https://stackoverflow.com/a/12030785/538387, non mi aiuta.

risposta

22

Qui si crea un HttpMessageHandler che cortocircuita la richiesta e non consente alla richiesta di passare attraverso il resto della pipeline. Invece, dovresti creare uno DelegatingHandler.

Inoltre ci sono 2 tipi di pipeline di gestione messaggi nell'API Web. Uno è una pipeline regolare in cui tutte le richieste di tutte le rotte passano e altre in cui si possono avere gestori di messaggi specifici solo su determinati percorsi.

  1. cercare di creare un DelegatingHandler e aggiungerlo alla lista d' tuoi HttpConfiguration di gestori di messaggi:

    config.MessageHandlers.Add(new HandlerA()) 
    
  2. Se si desidera aggiungere un gestore di percorso messaggio specifico, allora si potrebbe fare quanto segue :

    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 mostra la tubi con ne flusso.

+0

Grazie. La soluzione (1) funziona bene. Ma il numero 2, 'new HttpControllerDispatcher()' dice: ** System.Web.HttpDispatcher.HttpControllerDispatcher non contiene un costruttore che accetta 0 argomenti ** - Aggiornamento: ho corretto il codice. Grazie. – Tohid

+0

ho aggiornato anche il mio post sopra.grazie. –

+0

Per favore aggiungi anche questa parte della risposta di Cuong Le alla tua risposta: ** Per scrivere un gestore di messaggi personalizzato, dovresti derivare da 'System.Net.Http.DelegatingHandler'. ** – Tohid

11

Per scrivere un gestore di messaggio personalizzato, si dovrebbe derivare da 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); 
    } 
} 

E chiamare base.SendAsync per inviare la richiesta al gestore interiore.

+2

@Cuonge Le - Grazie per la risposta. Dopo aver sostituito 'CustomMessageHandler' con il tuo codice, genera un errore su' return base.SendAsync (request, cancellationToken); 'dicendo: ** Il gestore interno non è stato assegnato. **. Cosa mi sono perso di nuovo? – Tohid

+0

@Counge Le - La combinazione della tua risposta e di Kirran Chall, ha risolto il problema. Grazie ancora. – Tohid

+0

@Cuong Le qual è l'equivalente per .NET 4.0? Non riuscivo a trovare DelegatingHandler per .NET .4 ... come posso fare il messagehandling in 4.0. Grazie per l'aiuto. – jaxxbo

Problemi correlati