So implementieren Sie einen DelegatingHandler für X-HTTP-Methodenüberschreibung in der Web-API

Wenn Sie Ihre REST-Web-API über eine öffentliche Domäne bereitstellen, treten manchmal Probleme auf, die mit der Unterstützung von HTTP-Verben zusammenhängen. Die beiden Herausforderungen in dieser Hinsicht sind die eingeschränkte Unterstützung für HTTP-Verben in alten Webbrowsern (dh sie unterstützen nur HTTP GET und HTTP POST) und aggressive Firewalls, die Datenverkehr blockieren, der weder ein HTTP GET noch ein HTTP POST ist. Wie unterstützt Ihre Anwendung in diesen Fällen einen PUT oder DELETE? Genau hier setzt der HTTP-Header X-HTTP-Method-Override an.

Der HTTP-Header X-HTTP-Method-Override funktioniert ähnlich wie ein Hack. Sie können den Header mit dem Wert PUT oder DELETE hinzufügen, wenn Sie Ihre Web-API über JavaScript oder über ein XMLHttpRequestObjekt aus einem Webbrowser mithilfe eines HTTP-POST-Aufrufs aufrufen. Anschließend kann ein delegierender Handler die aufzurufende HTTP-Methode abfangen und die entsprechenden Aktionen ausführen.

In diesem Artikel werde ich erläutern, wie wir einen delegierenden Handler vor der Anforderungs-Antwort-Pipeline verwenden können, um die Anforderung zum Senden einer gültigen Nachricht an unsere Anwendung oder die Antwort zum Zurücksenden einer gültigen Antwort an den Client zu ändern.

HTTP-Verben und delegierende Handler

Wenn wir aufgrund von Einschränkungen, die von Ihrem Client, dem Webbrowser oder der Firewall vor Ihrer Webanwendung auferlegt werden, nur die HTTP-Verben GET und POST verwenden dürfen, müssen wir eine Problemumgehung implementieren, um PUT und DELETE zu unterstützen. Diese Problemumgehung umfasst normalerweise das Hinzufügen des HTTP-Headers X-HTTP-Method-Override zu der Anforderung, die das Verb angibt, das im HTTP-POST-Aufruf verwendet werden soll. Darüber hinaus benötigen wir in unserer Anwendung einen delegierenden Handler, der nach dem Header sucht und, falls vorhanden, die HTTP-Methode aufruft, die aufgerufen werden soll.

Bevor wir uns mit der Implementierung befassen, werfen wir einen kurzen Blick darauf, was delegierende Handler sind und warum wir hier einen verwenden würden. Ein delegierender Handler und andere Nachrichtenhandler werden früh in der Anforderungsverarbeitungspipeline ausgeführt. Dies sind Klassen, die HTTP-Anforderungen akzeptieren und eine HTTP-Antwort zurückgeben. Delegierende Handler ähneln denen HttpModulesin ASP.Net. Im Gegensatz dazu HttpModuleskönnen delegierende Handler verkettet werden: Ein delegierender Handler kann auf einen anderen delegierenden Handler verweisen. Weitere Informationen zum Delegieren von Handlern finden Sie in meinem vorherigen Artikel „Arbeiten mit Nachrichtenhandlern in der Web-API“.

Erstellen Sie einen Web-API-Controller

Angenommen, Sie haben einen ähnlichen Web-API-Controller:

öffentliche Klasse AuthorsController: ApiController

    {

        // GET: API / Autoren

        public IEnumerable Get ()

        {

            neuen String zurückgeben [] {“Joydip”, “Kanjilal”};

        }}

        // GET: api / autoren / 1

        public string Get (int id)

        {

            Rückgabe "Joydip Kanjilal";

        }}

        // POST api / author

        public void Post ([FromBody] Autorenwert) {}

        // PUT api / author / 1

        public void Put (int id, [FromBody] Autorenwert) {}

        // DELETE api / author / 1

        public void Delete (int id) {}

    }}

Erstellen Sie einen DelegatingHandler für X-HTTP-Method-Override

Implementieren wir nun einen X-HTTP-Method-Override-Handler. Dies ist ein Nachrichtenhandler, daher sollte er wie üblich die DelegatingHandlerKlasse erweitern.

öffentliche Klasse CustomMessageHandler: DelegatingHandler

    {

        schreibgeschützter String [] httpMethodsList = {"DELETE", "HEAD", "PUT"};

        const string httpMethodOverrideheader;

        geschützte Überschreibung Task SendAsync (HttpRequestMessage-Anforderung, CancellationToken CancellationToken)

        {

            if (request.Method == HttpMethod.Post && request.Headers.Contains (httpMethodOverrideheader))

            {               

                var httpMethod = request.Headers.GetValues ​​(httpMethodOverrideheader) .FirstOrDefault ();

                if (httpMethodsList.Contains (httpMethod, StringComparer.InvariantCultureIgnoreCase))

                {                  

                    request.Method = new HttpMethod (httpMethod);

                }}

            }}

            return base.SendAsync (Anfrage, CancellationToken);

        }}

    }}

Der Code ist selbsterklärend. Es wird nach einem HTTP-POST mit dem Header X-HTTP-Method-Override gesucht. Befindet sich der Header in der Liste der Methoden, wird die Anforderungsmethode geändert.

Registrieren Sie den DelegatingHandler

Der nächste Schritt ist die Registrierung des Handlers. Sie können dies tun, indem Sie diesen neuen Handler zur MessageHandlers-Auflistung in der WebApiConfig-Klasse hinzufügen, wie im folgenden Codeausschnitt gezeigt.

öffentliches statisches ungültiges Register (HttpConfiguration config)

{

    config.MessageHandlers.Add (neuer CustomMessageHandler ());

     // Web-API-Routen

    config.MapHttpAttributeRoutes ();

     config.Routes.MapHttpRoute (

        Name: "DefaultApi",

        routeTemplate: "api / {controller} / {id}",

        Standardeinstellungen: new {id = RouteParameter.Optional}

    );

}}

Alternativ können Sie den delegierenden Handler mithilfe des Application_StartEreignishandlers in der Datei Global.asax.cs wie unten gezeigt registrieren .

protected void Application_Start (Objektabsender, EventArgs e)

        {

            RegisterRoutes (RouteTable.Routes);

            GlobalConfiguration.Configuration.MessageHandlers.Add (neuer CustomMessageHandler ());

        }}

Das ist alles, was Sie auf der Serverseite tun müssen. Auf der Clientseite, dh über den Webbrowser, sollten Sie sicherstellen, dass Sie den Überschreibungsheader hinzufügen, wie im folgenden Codeausschnitt gezeigt.

$ .ajax ({

  URL: "// localhost: 9820 / api / Authors / 1",

  Typ: "POST",

  Daten: JSON.stringify (authorData),

  Überschriften: {

      "Inhaltstyp": "application / json",

      "X-HTTP-Method-Override": "PUT"},

})

Wie Sie im vorherigen Codeausschnitt sehen können, müssen Sie lediglich die HTTP-Methode angeben, die Sie im Anforderungsheader aufrufen möchten - X-HTTP-Method-Override : DELETEoder X-HTTP-Method-Override : PUT- und dann einen POST-Aufruf an Ihre Ressource ausführen .