2 votes

Pourquoi mon DelegatingHandler se déclenche-t-il pour les demandes MVC ?

J'ai un projet hybride MVC/Web API et j'ai ajouté une implémentation simple de DelegatingHandler pour envelopper les réponses API. Cela fonctionne parfaitement, mais le gestionnaire est également invoqué pour les demandes adressées aux contrôleurs MVC. D'après ce que j'ai compris, les DelegatingHandlers ne sont invoqués que pour les routes API.

J'utilise OWIN et quelques routes d'attributs si cela a de l'importance. Le code pertinent dans Startup.cs est le suivant :

var config = new HttpConfiguration();
// ...
var debugging = HttpContext.Current == null || HttpContext.Current.IsDebuggingEnabled;
config.MessageHandlers.Add(new ApiResponseDelegatingHandler(debugging));

Ainsi, les requêtes API et web sont enveloppées et envoyées en JSON. En le commentant, le problème est résolu mais les requêtes API ne sont pas enveloppées. Le message d'erreur sur une page Web est le suivant :

Aucune ressource HTTP correspondant à l'URI de la demande 'xxx' n'a été trouvée. Non données d'itinéraire n'ont été trouvées pour cette demande.

J'ai essayé de forcer l'ordre dans lequel les routes sont enregistrées afin que les routes MVC soient ajoutées avant l'API Web, mais cela n'a pas aidé.

1voto

Jamie Ide Points 28680

C'est facile à reproduire et je ne suis pas sûr qu'il s'agisse d'un bogue ou non.

  • Créez une nouvelle application Web en utilisant le modèle ASP.NET MVC.
  • Installez les modules Microsoft.AspNet.WebApi.Owin et paquets NuGet Microsoft.Owin.Host.SystemWeb
  • Déplacer le démarrage de l'API Web de WebApiConfig.cs vers un nouveau fichier Startup.cs
  • Créer un DelegatingHandler et l'ajouter à config.MessageHandlers dans la classe Startup
  • Le DelegatingHandler sera invoqué pour les demandes MVC et API.

J'ai essayé plusieurs combinaisons d'initialisation dans Startup.cs et WebApiConfig.cs sans succès. Si vous n'utilisez pas le routage par attributs, la solution consiste à ajouter le gestionnaire à la route. Dans ce cas, la seule solution que j'ai trouvée est d'examiner la route dans le gestionnaire et de n'envelopper la réponse API que si la route commence par "/api/".

public class WtfDelegatingHandler : DelegatingHandler
{
    protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var response = await base.SendAsync(request, cancellationToken);

        if (request.RequestUri.LocalPath.StartsWith("/api/", StringComparison.OrdinalIgnoreCase))
        {
            response = new HttpResponseMessage()
            {
                StatusCode = HttpStatusCode.OK,
                Content = new StringContent("I'm an API response")
            };
        }

        return response;
    }

}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X