Programmering

Sådan arbejder du med meddelelsesbehandlere i Web API

Beskedhåndterere i Web API giver dig mulighed for at behandle, redigere eller afvise en indgående anmodning, inden den når HttpControllerDispatcher. Beskedhåndterere udføres meget tidligere i anmodningen om behandling af anmodninger, og derfor er de et godt sted at implementere tværgående bekymringer i Web API.

Implementering af en brugerdefineret beskedhåndterer

Alle meddelelsesbehandlere stammer fra klassen HttpMessageHandler. For at opbygge din egen beskedhåndterer skal du udvide klassen DelegatingHandler. Bemærk, at DelegatingHandler-klassen til gengæld stammer fra HttpMessageHandler-klassen.

Overvej følgende Web API-controller.

offentlig klasse DefaultController: ApiController

    {

offentlig HttpResponseMessage Get ()

        {

returner Request.CreateResponse (HttpStatusCode.OK, "Inde i standard Web API Controller ...");

        }

    }

For at oprette en beskedhåndterer skal du udvide klassen DelegatingHandler og tilsidesætte metoden SendAsync.

offentlig klasse Handler: DelegatingHandler

    {

beskyttet tilsidesættelse async Opgave SendAsync (HttpRequestMessage anmodning, CancellationToken cancellationToken)

        {

return base.SendAsync (anmodning, cancellationToken);

        }

    }

Web-API-anmodningen behandlingsrørledning inkluderer et par indbyggede meddelelseshåndterere. Disse inkluderer følgende:

  • HttpServer - dette bruges til at hente anmodningen fra værten
  • HttpRoutingDispatcher - dette bruges til at sende anmodningen baseret på den konfigurerede rute
  • HttpControllerDispatcher - dette bruges til at sende anmodningen til den respektive controller

Du kan tilføje beskedhåndterere til pipelinen for at udføre en eller flere af følgende handlinger.

  • Udfør godkendelse og godkendelse
  • Logning af indgående anmodninger og udgående svar
  • Føj svaroverskrifter til svarobjekterne
  • Læs eller rediger anmodningsoverskrifter

Følgende kodestykke viser, hvordan du kan implementere en simpel beskedhåndterer i Web API.

offentlig klasse Handler: DelegatingHandler

{

beskyttet async tilsidesættelse Opgave SendAsync (HttpRequestMessage anmodning, CancellationToken cancellationToken)

        {

var respons = ny HttpResponseMessage (HttpStatusCode.OK)

            {

Content = new StringContent ("Inde i meddelelsesbehandleren ...")

            };

var task = new TaskCompletionSource ();

task.SetResult (svar);

opgave, der venter tilbage. Opgave;

        }

}

Meddelelsesbehandleren behandler ikke anmodningsmeddelelsen - den opretter svarmeddelelse og returnerer den derefter. Du kan også ringe til basisversionen af ​​SendAsync-metoden, hvis du ikke vil gøre noget med den indgående anmodning som vist i nedenstående kodeliste.

offentlig klasse Handler: DelegatingHandler

{

beskyttet async tilsidesættelse Opgave SendAsync (HttpRequestMessage anmodning, CancellationToken cancellationToken)

        {

return afventer base.SendAsync (anmodning, cancellationToken);

        }

}

Du kan også skrive kode for at logge Http-anmodningerne og de svar, der går ud i SendAsync-metoden.

For at udføre Web API kan du bruge en testmetode som den nedenfor.

 [Testmetode]

offentlig ugyldig WebAPIControllerTest ()

        {

HttpClient-klient = ny HttpClient ();

var result = client.GetAsync (ny Uri ("// localhost // api / default /")) Resultat;

streng responseMessage = result.Content.ReadAsStringAsync (). Resultat;

Assert.IsTrue (result.IsSuccessStatusCode);

        }

Når du udfører testmetoden, returneres meddelelsen "Inde i standard-web-API-controller ..." som en svarmeddelelse, og testen går. Åh! Vi oprettede en beskedhåndterer, men vi skal endnu ikke registrere den i pipeline til meddelelseshåndtering.

Du bliver nu nødt til at lade Web API-infrastrukturen vide, hvor din brugerdefinerede handler findes. For at gøre dette skal du registrere din brugerdefinerede handler i pipelinen. Du kan registrere den brugerdefinerede beskedhåndterer, vi lige har oprettet, i Registreringsmetoden i WebApiConfig-klassen som vist nedenfor.

offentligt statisk ugyldigt register (HttpConfiguration config)

{

GlobalConfiguration.Configuration.MessageHandlers.Add (ny håndterer ());

}

Når du udfører testmetoden igen, returneres tekstbeskeden "Inde i loggningshåndteringen ..." som en svarmeddelelse, og testen går.

Bemærk, at du også kan registrere flere beskedhåndterere til meddelelseshåndteringsrørledningen som vist i kodestykket nedenfor.

offentligt statisk ugyldigt register (HttpConfiguration config)

{

GlobalConfiguration.Configuration.MessageHandlers.Add (ny MessageHandlerA ());

GlobalConfiguration.Configuration.MessageHandlers.Add (ny MessageHandlerB ());

GlobalConfiguration.Configuration.MessageHandlers.Add (ny MessageHandlerC ());

}

Beskedhåndtererne udføres i den rækkefølge, som de er blevet føjet til rørledningen, og svaret returneres i omvendt rækkefølge. Med andre ord, på tidspunktet for den indgående anmodning, udføres meddelelseshåndtererne i den rækkefølge, de er registreret i. Under det udgående svar vendes processen bare. Så meddelelseshåndtererne udføres i omvendt rækkefølge af deres registrering til pipelinen.

Du kan også implementere en beskedhåndterer, der inspicerer den indgående anmodning og kontrollerer, om anmodningen indeholder en gyldig api-nøgle. Hvis api-nøglen ikke er til stede eller ikke er gyldig, returnerer den en passende fejlmeddelelse. Følgende kodeliste viser, hvordan du kan gøre dette - Jeg overlader det til dig at skrive koden for at validere api-nøglen alligevel.

beskyttet tilsidesættelse Opgave SendAsync (HttpRequestMessage anmodning, CancellationToken cancellationToken)

        {

streng nøgle = HttpUtility.ParseQueryString (anmodning.RequestUri.Query) .Get ("nøgle");

string errorMessage = "Du skal angive api-nøglen for at få adgang til Web API.";

prøve

            {

hvis (! streng.IsNullOrWhiteSpace (nøgle))

                {

return base.SendAsync (anmodning, cancellationToken);

                }

andet

                {

HttpResponseMessage response = request.CreateErrorResponse (HttpStatusCode.Forbidden, errorMessage);

smid nyt HttpResponseException (svar);

                }

            }

fangst

            {

HttpResponseMessage response = request.CreateErrorResponse (HttpStatusCode.InternalServerError, "Der opstod en uventet fejl ...");

smid nyt HttpResponseException (svar);

            }

        }