Cara melaksanakan DelegatingHandler untuk X-HTTP-Method-Override di Web API

Semasa menggunakan API Web REST anda melalui domain awam, anda kadang-kadang akan menghadapi masalah yang berkaitan dengan sokongan untuk kata kerja HTTP. Dua cabaran dalam hal ini adalah sokongan terhad untuk kata kerja HTTP pada penyemak imbas web lama (iaitu mereka hanya menyokong HTTP GET dan HTTP POST) dan firewall agresif yang menyekat lalu lintas yang bukan merupakan HTTP GET atau HTTP POST. Bagaimana aplikasi anda menyokong PUT atau DELETE dalam kes ini? Inilah tepatnya tajuk X-HTTP-Method-Override HTTP untuk menyelamatkan.

Header HTTP X-HTTP-Method-Override berfungsi agak serupa dengan hack. Anda dapat menambahkan header dengan nilai PUT atau DELETE ketika memanggil API Web anda melalui JavaScript atau melalui XMLHttpRequestobjek dari penyemak imbas web menggunakan panggilan HTTP POST. Anda kemudian boleh meminta pengendali perwakilan memintas kaedah HTTP untuk dipanggil dan mengambil tindakan yang sesuai.

Dalam artikel ini saya akan membincangkan bagaimana kita dapat menggunakan pengendali perwakilan di depan saluran permintaan-respons untuk mengubah permintaan untuk mengirim pesan yang valid ke aplikasi kita, atau mengubah respons untuk mengirim kembali respons yang valid kepada klien.

Kata kerja HTTP dan pengendali perwakilan

Sekiranya kita dibatasi untuk menggunakan hanya kata kerja HTTP GET dan POST kerana batasan yang dikenakan oleh pelanggan anda, penyemak imbas web, atau firewall yang menghadap aplikasi web anda, kami harus melaksanakan penyelesaian untuk menyokong PUT dan DELETE. Penyelesaian ini biasanya melibatkan penambahan header HTTP X-HTTP-Method-Override ke permintaan yang menentukan kata kerja yang ingin kita gunakan dalam panggilan HTTP POST. Sebagai tambahan, kami memerlukan pengendali perwakilan dalam aplikasi kami yang memeriksa header dan, jika ada, membuat panggilan ke kaedah HTTP yang ingin anda gunakan.

Sebelum kita menyelidiki pelaksanaannya, mari kita lihat dengan cepat apa pengendali delegasi dan mengapa kita menggunakannya di sini. Pengendali perwakilan dan pengendali mesej lain dilaksanakan pada awal proses pemprosesan permintaan. Ini adalah kelas yang menerima permintaan HTTP dan mengembalikan respons HTTP. Pengendali delegasi serupa dengan HttpModulesdi ASP.Net. Tetapi tidak seperti HttpModules, pengendali perwakilan dapat dirantai: Satu pengendali perwakilan dapat merujuk pengendali perwakilan yang lain. Anda boleh mengetahui lebih lanjut mengenai mewakilkan pengendali dari artikel saya sebelumnya, "Cara bekerja dengan pengendali mesej di API Web."

Buat pengawal API Web

Andaikan anda mempunyai pengawal API Web yang serupa dengan ini:

kelas awam AuthorsController: ApiController

    {

        // DAPATKAN: api / pengarang

        awam IEnumerable Get ()

        {

            kembalikan rentetan baru [] {“Joydip”, “Kanjilal”};

        }

        // DAPATKAN: api / pengarang / 1

        rentetan awam Dapatkan (int id)

        {

            kembalikan "Joydip Kanjilal";

        }

        // POST api / pengarang

        kekosongan awam Post ([FromBody] Nilai pengarang) {}

        // PUT api / pengarang / 1

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

        // HAPUS api / pengarang / 1

        kekosongan awam Padam (int id) {}

    }

Buat DelegatingHandler untuk Kaedah X-HTTP-Override

Sekarang mari kita laksanakan pengendali X-HTTP-Method-Override. Ini adalah pengendali mesej, jadi seperti biasa ia harus melanjutkan DelegatingHandlerkelas.

kelas awam CustomMessageHandler: DelegatingHandler

    {

        rentetan baca [] httpMethodsList = {“DELETE”, “HEAD”, “PUT”};

        string const httpMethodOverrideheader;

        override dilindungi Task SendAsync (Permintaan HttpRequestMessage, PembatalanToken pembatalanToken)

        {

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

            {               

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

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

                {                  

                    request.Method = HttpMethod baru (httpMethod);

                }

            }

            pangkalan kembali.SendAsync (permintaan, pembatalanToken);

        }

    }

Kodnya cukup jelas. Ia memeriksa HTTP POST yang mempunyai header X-HTTP-Method-Override. Sekiranya tajuk dalam senarai kaedah, kaedah permintaan diubah.

Daftarkan DelegatingHandler

Langkah seterusnya adalah mendaftarkan pengendali. Anda boleh melakukannya dengan menambahkan pengendali baru ini ke koleksi MessageHandlers di kelas WebApiConfig seperti yang ditunjukkan dalam coretan kod di bawah.

Daftar tidak sah awam (konfigurasi HttpConfiguration)

{

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

     // Laluan API Web

    config.MapHttpAttributeRoutes ();

     config.Routes.MapHttpRoute (

        nama: "DefaultApi",

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

        lalai: baru {id = RouteParameter.Optional}

    );

}

Sebagai alternatif, anda boleh mendaftarkan pengendali perwakilan menggunakan Application_Startpengendali acara dalam fail Global.asax.cs seperti yang ditunjukkan di bawah.

dilindungi void Application_Start (penghantar objek, EventArgs e)

        {

            RegisterRoutes (RouteTable.Routes);

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

        }

Itu sahaja yang harus anda lakukan di sisi pelayan. Di sisi klien, iaitu dari penyemak imbas web, anda harus memastikan bahawa anda menambahkan tajuk pengganti seperti yang ditunjukkan dalam coretan kod di bawah.

$ .ajax ({

  url: "// localhost: 9820 / api / Pengarang / 1",

  taip: "POST",

  data: JSON.stringify (authorData),

  tajuk: {

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

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

})

Seperti yang anda lihat dalam coretan kod sebelumnya, yang perlu anda lakukan adalah menentukan kaedah HTTP yang ingin anda gunakan dalam tajuk permintaan - X-HTTP-Method-Override : DELETEatau X-HTTP-Method-Override : PUT- dan kemudian membuat panggilan POST ke sumber anda.