Programování

Jak pracovat s obslužnými rutinami zpráv ve webovém rozhraní API

Obslužné rutiny zpráv ve webovém rozhraní API vám poskytují příležitost zpracovat, upravit nebo odmítnout příchozí požadavek, než dosáhne HttpControllerDispatcher. Obslužné rutiny zpráv se spouštějí mnohem dříve v kanálu zpracování požadavků, a proto jsou skvělým místem pro implementaci průřezových problémů ve webovém rozhraní API.

Implementace vlastní obslužné rutiny zpráv

Všechny obslužné rutiny zpráv pocházejí z třídy HttpMessageHandler. Chcete-li vytvořit svůj vlastní obslužný program zpráv, měli byste rozšířit třídu DelegatingHandler. Všimněte si, že DelegatingHandler třída zase pochází z HttpMessageHandler třídy.

Zvažte následující řadič webového rozhraní API.

veřejná třída DefaultController: ApiController

    {

veřejné HttpResponseMessage Get ()

        {

return Request.CreateResponse (HttpStatusCode.OK, "Inside the Default Web API Controller ...");

        }

    }

Chcete-li vytvořit obslužnou rutinu zprávy, musíte rozšířit DelegatingHandler třídu a přepsat SendAsync metodu.

obsluha veřejné třídy: DelegatingHandler

    {

chráněné přepsání asynchronní úloha SendAsync (požadavek HttpRequestMessage, CancellationToken CancelToken)

        {

návrat base.SendAsync (požadavek, zrušeníToken);

        }

    }

Kanál zpracování požadavků webového API obsahuje několik předdefinovaných obslužných rutin zpráv. Patří mezi ně následující:

  • HttpServer - slouží k načtení požadavku z hostitele
  • HttpRoutingDispatcher - používá se k odeslání požadavku na základě nakonfigurované trasy
  • HttpControllerDispatcher - slouží k odeslání požadavku příslušnému řadiči

Můžete přidat obslužné rutiny zpráv do kanálu k provedení jedné nebo více z následujících operací.

  • Proveďte ověřování a autorizaci
  • Protokolování příchozích požadavků a odchozích odpovědí
  • Přidejte záhlaví odpovědí k objektům odpovědi
  • Přečtěte si nebo upravte záhlaví požadavků

Následující fragment kódu ukazuje, jak můžete implementovat jednoduchý obslužný program zpráv ve webovém rozhraní API.

obsluha veřejné třídy: DelegatingHandler

{

chráněné přepsání async Úkol SendAsync (požadavek HttpRequestMessage, CancellationToken CancelToken)

        {

var response = new HttpResponseMessage (HttpStatusCode.OK)

            {

Content = new StringContent ("Inside the message handler ...")

            };

var task = new TaskCompletionSource ();

task.SetResult (response);

návrat čekat task.Task;

        }

}

Obslužná rutina zprávy zprávu požadavku nezpracuje - vytvoří zprávu s odpovědí a poté ji vrátí. Můžete také zavolat základní verzi metody SendAsync, pokud byste s příchozím požadavkem nechtěli nic dělat, jak je uvedeno v níže uvedeném seznamu kódů.

obsluha veřejné třídy: DelegatingHandler

{

chráněné přepsání async Úkol SendAsync (požadavek HttpRequestMessage, CancellationToken CancelToken)

        {

návrat čekají base.SendAsync (požadavek, zrušeníToken);

        }

}

Můžete také napsat kód pro protokolování požadavků Http a odpovědí, které vyšly v metodě SendAsync.

K provedení webového rozhraní API můžete použít testovací metodu, která je uvedena níže.

 [Testovací metoda]

public void WebAPIControllerTest ()

        {

HttpClient klient = nový HttpClient ();

var result = client.GetAsync (new Uri ("// localhost // api / default /")). Výsledek;

string responseMessage = result.Content.ReadAsStringAsync (). Výsledek;

Assert.IsTrue (result.IsSuccessStatusCode);

        }

Když provedete testovací metodu, zobrazí se zpráva „Uvnitř výchozího řadiče webového rozhraní API ...“ jako zpráva s odpovědí a test projde. Ach! Vytvořili jsme obslužnou rutinu zpráv, ale ještě ji nezaregistrujeme do kanálu zpracování zpráv.

Nyní byste museli dát infrastruktuře webového rozhraní API vědět, kde existuje vaše vlastní obslužná rutina. Chcete-li to provést, měli byste zaregistrovat vlastní obslužnou rutinu v potrubí. Můžete zaregistrovat vlastní obslužnou rutinu zpráv, kterou jsme právě vytvořili v Register metodě třídy WebApiConfig, jak je znázorněno níže.

public static void Register (HttpConfiguration config)

{

GlobalConfiguration.Configuration.MessageHandlers.Add (nový Handler ());

}

Když znovu spustíte testovací metodu, vrátí se textová zpráva „Uvnitř obslužné rutiny protokolovacích zpráv ...“ jako zpráva s odpovědí a test projde.

Všimněte si, že můžete také zaregistrovat více obslužných rutin zpráv do kanálu zpracování zpráv, jak je znázorněno v fragmentu kódu níže.

public static void Register (HttpConfiguration config)

{

GlobalConfiguration.Configuration.MessageHandlers.Add (nový MessageHandlerA ());

GlobalConfiguration.Configuration.MessageHandlers.Add (nový MessageHandlerB ());

GlobalConfiguration.Configuration.MessageHandlers.Add (nový MessageHandlerC ());

}

Obslužné rutiny zpráv by byly provedeny v pořadí, ve kterém byly přidány do kanálu, a odpověď by byla vrácena v opačném pořadí. Jinými slovy, v době příchozího požadavku se obslužné rutiny zpráv provádějí v pořadí, v jakém jsou zaregistrovány. Během odchozí odpovědi je proces pouze obrácen. Obslužné rutiny zpráv se tedy provádějí v obráceném pořadí jejich registrace do kanálu.

Můžete také implementovat obslužnou rutinu zprávy, která zkontroluje příchozí požadavek a zkontroluje, zda požadavek obsahuje platný klíč API. Pokud klíč api není k dispozici nebo není platný, vrátí příslušnou chybovou zprávu. Následující výpis kódu ukazuje, jak to můžete udělat - nechám na vás, abyste kód napsali, abyste stejně ověřili klíč API.

chráněné přepsání úlohy SendAsync (požadavek HttpRequestMessage, CancellationToken zrušeníToken)

        {

string key = HttpUtility.ParseQueryString (request.RequestUri.Query) .Get ("klíč");

string errorMessage = "Musíte zadat klíč api pro přístup k webovému API.";

Snaž se

            {

if (! string.IsNullOrWhiteSpace (klíč))

                {

návrat base.SendAsync (požadavek, zrušeníToken);

                }

jiný

                {

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

hodit novou HttpResponseException (odpověď);

                }

            }

chytit

            {

HttpResponseMessage response = request.CreateErrorResponse (HttpStatusCode.InternalServerError, "došlo k neočekávané chybě ...");

hodit novou HttpResponseException (odpověď);

            }

        }