Προγραμματισμός

Πώς να εφαρμόσετε ένα DelegatingHandler για X-HTTP-Method-Override στο Web API

Κατά την ανάπτυξη του REST Web API σε δημόσιο τομέα, μερικές φορές θα αντιμετωπίσετε προβλήματα που σχετίζονται με την υποστήριξη για ρήματα HTTP. Οι δύο προκλήσεις από την άποψη αυτή είναι η περιορισμένη υποστήριξη για ρήματα HTTP σε παλιά προγράμματα περιήγησης ιστού (δηλαδή υποστηρίζουν μόνο HTTP GET και HTTP POST) και επιθετικά τείχη προστασίας που εμποδίζουν την κίνηση που δεν είναι ούτε HTTP GET ή HTTP POST. Πώς θα υποστηρίξει η εφαρμογή σας ένα PUT ή DELETE σε αυτές τις περιπτώσεις; Εδώ ακριβώς βρίσκεται η διάσωση της κεφαλίδας X-HTTP-Method-Override HTTP.

Η κεφαλίδα HTTP X-HTTP-Method-Override λειτουργεί κάπως παρόμοια με ένα hack. Μπορείτε να προσθέσετε την κεφαλίδα με τιμή PUT ή DELETE όταν καλείτε το API Ιστού σας μέσω JavaScript ή μέσω XMLHttpRequest αντικείμενο από πρόγραμμα περιήγησης ιστού χρησιμοποιώντας μια κλήση HTTP POST. Στη συνέχεια, μπορείτε να ζητήσετε από έναν χειριστή ανάθεσης να παρακολουθεί τη μέθοδο HTTP και να προβεί στις κατάλληλες ενέργειες.

Σε αυτό το άρθρο θα συζητήσω πώς μπορούμε να χρησιμοποιήσουμε έναν χειριστή ανάθεσης μπροστά από τον αγωγό αίτησης-απάντησης για να αλλάξουμε το αίτημα για να στείλουμε ένα έγκυρο μήνυμα στην εφαρμογή μας ή να αλλάξω την απάντηση για να στείλουμε μια έγκυρη απάντηση στον πελάτη.

Ρήματα HTTP και χειριστές ανάθεσης

Εάν είμαστε υποχρεωμένοι να χρησιμοποιήσουμε μόνο τα ρήματα HTTP GET και POST λόγω περιορισμών που επιβάλλονται από τον πελάτη σας, το πρόγραμμα περιήγησης ιστού ή το τείχος προστασίας που βρίσκεται μπροστά από την εφαρμογή ιστού σας, θα πρέπει να εφαρμόσουμε μια λύση για την υποστήριξη PUT και DELETE. Αυτή η λύση συνήθως περιλαμβάνει την προσθήκη της κεφαλίδας HTTP X-HTTP-Method-Override στο αίτημα που καθορίζει το ρήμα που θέλουμε να χρησιμοποιήσουμε στην κλήση HTTP POST. Επιπλέον, χρειαζόμαστε έναν χειριστή ανάθεσης στην εφαρμογή μας που ελέγχει την κεφαλίδα και, εάν υπάρχει, πραγματοποιεί την κλήση στη μέθοδο HTTP που θέλετε να καλέσετε.

Πριν βυθίσουμε την εφαρμογή, ας ρίξουμε μια γρήγορη ματιά σε τι είναι οι διαχειριστές ανάθεσης και γιατί θα χρησιμοποιούσαμε έναν εδώ. Ένας χειριστής ανάθεσης και άλλοι χειριστές μηνυμάτων εκτελούνται νωρίς στη διαδικασία επεξεργασίας αιτημάτων. Αυτές είναι τάξεις που δέχονται αιτήματα HTTP και επιστρέφουν μια απόκριση HTTP. Οι διαχειριστές ανάθεσης είναι παρόμοιοι με αυτούς HttpModules στο ASP.Net. Αλλά σε αντίθεση με HttpModules, οι χειριστές ανάθεσης μπορούν να αλυσοδεθούν: Ένας χειριστής ανάθεσης μπορεί να αναφέρει έναν άλλο χειριστή ανάθεσης. Μπορείτε να μάθετε περισσότερα σχετικά με την ανάθεση χειριστών από το προηγούμενο άρθρο μου, "Πώς να συνεργαστείτε με προγράμματα χειρισμού μηνυμάτων στο Web API".

Δημιουργία ελεγκτή API Ιστού

Ας υποθέσουμε ότι έχετε έναν ελεγκτή API Ιστού παρόμοιο με αυτό:

δημόσια τάξη AuthorsController: ApiController

    {

// GET: api / συγγραφείς

δημόσια IEnumerable Get ()

        {

επιστροφή νέας συμβολοσειράς [] {“Joydip”, “Kanjilal”};

        }

// GET: api / συγγραφείς / 1

δημόσια συμβολοσειρά Get (int id)

        {

επιστροφή "Joydip Kanjilal";

        }

// POST api / συγγραφέας

δημόσια άκυρη δημοσίευση ([FromBody] Τιμή συγγραφέα) {}

// PUT api / συγγραφέας / 1

public void Put (int id, [FromBody] Τιμή συγγραφέα) {}

// ΔΙΑΓΡΑΦΗ api / συγγραφέας / 1

δημόσιο κενό Διαγραφή (int id) {}

    }

Δημιουργήστε ένα DelegatingHandler για X-HTTP-Method-Override

Τώρα ας εφαρμόσουμε ένα πρόγραμμα χειρισμού X-HTTP-Method-Override. Αυτός είναι ένας χειριστής μηνυμάτων, οπότε ως συνήθως πρέπει να επεκτείνει το Ανάθεση χειριστή τάξη.

δημόσια τάξη CustomMessageHandler: DelegatingHandler

    {

συμβολοσειρά readonly [] httpMethodsList = {“DELETE”, “HEAD”, “PUT”};

const string httpMethodOverrideheader;

προστατευμένη παράκαμψη Εργασία SendAsync (HttpRequestMessage request, CancellationToken ακύρωσηToken)

        {

εάν (request.Method == HttpMethod.Post && request.Headers.Contains (httpMethodOverrideheader))

            {               

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

εάν (httpMethodsList.Contains (httpMethod, StringComparer.InvariantCultureIgnoreCase))

                {                  

request.Method = νέο HttpMethod (httpMethod);

                }

            }

βάση επιστροφής.SendAsync (αίτημα, ακύρωση κουπόνι);

        }

    }

Ο κωδικός είναι αρκετά αυτονόητος. Ελέγχει για HTTP POST που έχει την κεφαλίδα X-HTTP-Method-Override. Εάν η κεφαλίδα βρίσκεται στη λίστα μεθόδων, η μέθοδος αιτήματος αλλάζει.

Καταχωρήστε το DelegatingHandler

Το επόμενο βήμα είναι η εγγραφή του χειριστή. Μπορείτε να το κάνετε προσθέτοντας αυτόν τον νέο χειριστή στη συλλογή MessageHandlers στην κλάση WebApiConfig, όπως φαίνεται στο απόσπασμα κώδικα παρακάτω.

Δημόσιο στατικό άκυρο Μητρώο (HttpConfiguration config)

{

config.MessageHandlers.Add (νέο CustomMessageHandler ());

// Διαδρομές API Ιστού

config.MapHttpAttributeRoutes ();

config.Routes.MapHttpRoute (

όνομα: "DefaultApi",

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

προεπιλογές: νέο {id = RouteParameter.Optional}

    );

}

Εναλλακτικά, μπορείτε να καταχωρήσετε τον χειριστή ανάθεσης χρησιμοποιώντας το Εφαρμογή_Έναρξη χειριστής συμβάντων στο αρχείο Global.asax.cs όπως φαίνεται παρακάτω.

protected void Application_Start (αποστολέας αντικειμένου, EventArgs e)

        {

RegisterRoutes (RouteTable.Routes);

GlobalConfiguration.Configuration.MessageHandlers.Add (νέο CustomMessageHandler ());

        }

Αυτό είναι το μόνο που έχετε να κάνετε από την πλευρά του διακομιστή. Από την πλευρά του πελάτη, δηλαδή από το πρόγραμμα περιήγησης ιστού, πρέπει να βεβαιωθείτε ότι έχετε προσθέσει την κεφαλίδα παράκαμψης, όπως φαίνεται στο παρακάτω απόσπασμα κώδικα.

$ .ajax ({

url: "// localhost: 9820 / api / Συγγραφείς / 1",

πληκτρολογήστε: "POST",

δεδομένα: JSON.stringify (authorData),

κεφαλίδες: {

"Content-Type": "application / json",

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

})

Όπως μπορείτε να δείτε στο προηγούμενο απόσπασμα κώδικα, το μόνο που χρειάζεται να κάνετε είναι να καθορίσετε τη μέθοδο HTTP που θέλετε να επικαλεστείτε στην κεφαλίδα του αιτήματος—X-HTTP-Method-Override: ΔΙΑΓΡΑΦΗ ή X-HTTP-Method-Override: PUT- και, στη συνέχεια, πραγματοποιήστε μια κλήση POST στον πόρο σας.