ไม่มีส่วนหัวการตอบกลับใน DelegatingHandler

ฉันกำลังพยายามบันทึก HTTP Response Headers ของโปรเจ็กต์ Web API ของฉัน

โครงการนี้พัฒนาโดย VS2012, .NET 4.5 และ ASP.NET MVC 4

ฉันได้เขียนคลาสย่อย DelegatingHandler ดังนี้:

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;
        });
    }
}

อย่างไรก็ตาม ปัญหาคือ ฉันไม่สามารถรับค่าส่วนหัวจาก response ได้ response.Headers เป็นคอลเล็กชันที่ว่างเปล่า response.Content.Headers ไม่มีอะไรเลยนอกจากคีย์ชื่อ Content-Type และ HttpContext.Current คือ null

ฉันเคยเห็นโค้ดของ WebAPIContrib ซึ่ง ใช้ตรรกะเดียวกันเพื่อบันทึกส่วนหัว แต่ดูเหมือนว่ารหัสจะไม่ทำงานเช่นกัน

ดังนั้นฉันจะติดตาม HTTP Response Headers ในโครงการ Web API ได้อย่างไร


person Zhao Xiang    schedule 22.08.2013    source แหล่งที่มา
comment
ปัญหาเดียวกันที่นี่ คุณมีวิธีแก้ปัญหาหรือไม่?   -  person erwineberhard    schedule 19.06.2015
comment
ไม่ ไม่เคยค้นพบสิ่งนั้น   -  person Zhao Xiang    schedule 23.06.2015
comment
ฉันได้แก้ไขปัญหานี้แล้วโดยการส่งส่วนหัวการตอบกลับไปยังไคลเอ็นต์ แทนที่จะเปลี่ยนข้อความตอบกลับในตัวจัดการการมอบหมาย ง่ายกว่ามากในกรอบงานจาวาสคริปต์ของฉันด้วย!   -  person erwineberhard    schedule 23.06.2015


คำตอบ (3)


ตัวจัดการข้อความจะถูกเรียกในลำดับเดียวกันกับที่ปรากฏในคอลเลกชัน MessageHandlers เนื่องจากซ้อนกันอยู่ ข้อความตอบกลับจึงเดินทางไปในทิศทางอื่น นั่นคือตัวจัดการคนสุดท้ายจะเป็นคนแรกที่ได้รับข้อความตอบกลับ

ตรวจสอบให้แน่ใจว่าตัวจัดการการบันทึกได้รับการลงทะเบียนตั้งแต่เนิ่นๆ ในไปป์ไลน์ ควรเป็นอันดับแรก

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...
    }
}

ด้วยวิธีนี้ตัวจัดการอื่นๆ จะมีโอกาสเติมคำตอบและบันทึกข้อมูลนั้นไว้

คุณยังสามารถลดความซับซ้อนของคลาสโดยใช้ไวยากรณ์ async/await เพื่อเข้าถึงตัวล้างการตอบสนอง

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
    }
}

ควรสามารถเข้าถึงรายละเอียดที่จำเป็นจากการตอบกลับก่อนส่งคืน

การอ้างอิง: ตัวจัดการข้อความ HTTP ใน ASP NET เว็บ API

person Nkosi    schedule 24.02.2017

ลองใช้โค้ดด้านล่างนี้

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
สิ่งนี้คล้ายกับตัวอย่างที่สองที่นี่: docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/ - person Josh; 18.01.2019

คุณต้องดูสถานที่ที่ถูกต้อง:

request.Content.Headers.ContentType

สมมติว่ามีส่วนหัวคำขอ Content-Type: application/json ดังนั้นสิ่งที่กล่าวมาข้างต้นจะส่งกลับ "application/json"

โดยพื้นฐานแล้วส่วนหัวบางส่วนจะเชื่อมโยงกับเนื้อหาและนั่นคือสิ่งที่คุณควรอ่านจากที่นี้

เช่นเดียวกับส่วนหัวการตอบกลับ คุณอาจต้องแยกเนื้อหาออกจากเนื้อหาการตอบกลับ ทั้งนี้ขึ้นอยู่กับประเภทของพวกเขา (สำหรับคำขอที่ส่งคืนเนื้อหา)

response.Content.Headers.ContentType
person Darin Dimitrov    schedule 21.02.2017
comment
นั่นจะไม่ได้รับส่วนหัว คำขอ ใช่ไหม ฉันต้องบันทึกส่วนหัวการตอบกลับทั้งหมด ไม่ใช่แค่ ContentType แต่การตอบกลับส่วนหัวว่างเปล่า - person Giorgi; 21.02.2017
comment
สิ่งเดียวกัน: response.Content.Headers - person Darin Dimitrov; 21.02.2017
comment
response.Content.Headers มีเพียง ContentType เท่านั้น ส่วนหัวอื่น ๆ (ความยาวเนื้อหา, แคช ฯลฯ ) ถูกเพิ่มโดย iis express ดังนั้นจึงไม่มีทางรับมันได้หรือไม่ - person Giorgi; 21.02.2017