Tidak Ada Header Respons di DelegatingHandler

Saya mencoba mencatat Header Respons HTTP dari proyek API Web saya.

Proyek ini dikembangkan oleh VS2012, .NET 4.5 dan ASP.NET MVC 4.

Saya telah menulis subkelas DelegatingHandler seperti ini:

public class LoggingHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {

        // Execute the request
        return base.SendAsync(request, cancellationToken).ContinueWith(task =>
        {
            var response = task.Result;
            return response;
        });
    }
}

Namun, masalahnya adalah, saya tidak bisa mendapatkan nilai header dari response. response.Headers adalah koleksi kosong, response.Content.Headers hanya berisi kunci bernama Content-Type, dan HttpContext.Current adalah null.

Saya telah melihat kode WebAPIContrib yang gunakan logika yang sama untuk mencatat header, tetapi kodenya sepertinya juga tidak berfungsi.

Jadi bagaimana cara melacak Header Respons HTTP di proyek API Web?


person Zhao Xiang    schedule 22.08.2013    source sumber
comment
Masalah yang sama disini. Apakah Anda punya solusi?   -  person erwineberhard    schedule 19.06.2015
comment
Tidak, tidak pernah mengetahuinya   -  person Zhao Xiang    schedule 23.06.2015
comment
Saya telah memecahkan masalah ini dengan mengirimkan header respons ke klien alih-alih mengubah pesan respons di penangan delegasi. Jauh lebih mudah dalam kerangka javascript saya juga!   -  person erwineberhard    schedule 23.06.2015


Jawaban (3)


Penangan pesan dipanggil dalam urutan yang sama dengan yang muncul di koleksi MessageHandlers. Karena bersifat bertumpuk, pesan respons bergerak ke arah lain. Artinya, penangan terakhir adalah yang pertama menerima pesan respons.

Pastikan penangan logging didaftarkan di awal alur. Sebaiknya yang pertama.

public static class WebApiConfig {
    public static void Register(HttpConfiguration config) {
        config.MessageHandlers.Add(new LoggingHandler(...));

        //...add other handlers
        config.MessageHandlers.Add(new MessageHandler1());
        config.MessageHandlers.Add(new MessageHandler2());

        // Other code not shown...
    }
}

Dengan begitu, penangan lain mana pun akan mempunyai kesempatan untuk mengisi respons dan mencatat informasi tersebut.

Anda juga dapat menyederhanakan kelas menggunakan sintaks async/await untuk membuat akses respons lebih bersih.

public class LoggingHandler : DelegatingHandler {
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {

        //...Extract and log request
        LogRequest(request);

        // Send the request on to the inner handler(s) and get the response
        var response = await base.SendAsync(request, cancellationToken);

        //...Extract details from response for logging
        LogResponse(response);

        return response;
    }

    private void LogRequest(HttpRequestMessage request) {
        //... code removed for brevity
    }

    private void LogResponse(HttpResponseMessage response) {
        //... code removed for brevity
    }
}

Harus dapat mengakses detail yang diperlukan dari respons sebelum mengembalikannya.

Referensi : Penanganan Pesan HTTP di ASP. API Web BERSIH

person Nkosi    schedule 24.02.2017

Cobalah kode di bawah ini.

return base.SendAsync(request, cancellationToken).ContinueWith(
                        task =>
                        {

                            var headers = task.Result.ToString();
                            var body = task.Result.Content.ReadAsStringAsync().Result;

                            // RETURN THE ORIGINAL RESULT
                            var response = task.Result;
                            return response;
                        }
            );
person Kalyan    schedule 23.02.2017
comment
Ini mirip dengan contoh kedua di sini: docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/ - person Josh; 18.01.2019

Anda harus melihat tempat yang tepat:

request.Content.Headers.ContentType

Dengan asumsi ada header permintaan Content-Type: application/json, maka yang disebutkan di atas akan mengembalikan "application/json".

Jadi pada dasarnya beberapa header dikaitkan dengan Konten dan dari situlah Anda harus membacanya.

Hal yang sama berlaku untuk header respons. Bergantung pada tipenya, Anda mungkin perlu mengekstraknya dari konten respons (untuk permintaan yang mengembalikan isi)

response.Content.Headers.ContentType
person Darin Dimitrov    schedule 21.02.2017
comment
Bukankah itu akan mendapatkan tajuk permintaan? Saya perlu mencatat semua header respons, bukan hanya ContentType tetapi respon.Headers kosong - person Giorgi; 21.02.2017
comment
Hal yang sama: response.Content.Headers - person Darin Dimitrov; 21.02.2017
comment
respon.Content.Headers hanya berisi ContentType. Apakah header lain (panjang konten, cache, dll) ditambahkan oleh iis express sehingga tidak ada cara untuk mendapatkannya? - person Giorgi; 21.02.2017