Message Handler คือ Class ที่รับ HTTP Request และคืน HTTP Response Message Handlers สืบทอดจาก Abstract Class HttpMessageHandler Message Handlers ให้โอกาส Process, Edit, หรือ Decline Incoming Request ก่อนถึง HttpControllerDispatcher
Message Handlers Execute ก่อนใน Request Processing Pipeline จึงเป็นที่เหมาะสำหรับ Cross-cutting Concerns ใน Web API Message Handlers คือ Chain ของ Classes (System-defined หรือ Custom) ที่อยู่ติดกันใน Pipeline ของ HTTP Request และ Response

ตัวอย่าง: HTTP Request เข้ามา → HandlerA → HandlerB → ... → Controller → Response กลับมาทางเดิม
สองประเภทของ Message Handlers ใน ASP.NET Web API
1. Server-Side HTTP Message Handlers
ฝั่ง Server Web API Pipeline ใช้ Built-in Message Handlers:
- HttpServer - รับ Request จาก Host
- HttpRoutingDispatcher - Dispatch Request ตาม Route
- HttpControllerDispatcher - ส่ง Request ไปยัง Web API Controller
เราสามารถเพิ่ม Custom Handlers เข้า Pipeline ได้ Message Handlers เหมาะสำหรับ Cross-cutting Concerns ที่ทำงานระดับ HTTP Messages (ไม่ใช่ Controller Actions) เช่น:
- อ่าน/แก้ไข Request Headers
- เพิ่ม Response Header
- Validate Requests ก่อนถึง Controller
2. Client-Side HTTP Message Handlers
ฝั่ง Client คลาส HttpClient ใช้ Message Handler ประมวลผล Request Default Handler คือ HttpClientHandler ซึ่งส่ง Request ผ่าน Network และรับ Response จาก Server เราสามารถ Insert Custom Message Handlers เข้า Client Pipeline ได้
Built-in Server Handlers รายละเอียด
| Handler | หน้าที่ | ลำดับใน Pipeline |
|---|---|---|
| HttpServer | Entry Point - รับ Request จาก Host (IIS/Self-host) | 1 (Outermost) |
| HttpRoutingDispatcher | เลือก Route, สร้าง RouteData, เลือก Controller | 2 |
| HttpControllerDispatcher | สร้าง Controller, เรียก Action, สร้าง Response | 3 (Innermost before Controller) |
Custom Server-Side Handler (DelegatingHandler)
public class CustomHeaderHandler : DelegatingHandler {
protected override async Task SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken) {
// Pre-processing: เพิ่ม Header ใน Request
request.Headers.Add("X-Custom-Request-Header", "Value");
var response = await base.SendAsync(request, cancellationToken);
// Post-processing: เพิ่ม Header ใน Response
response.Headers.Add("X-Custom-Response-Header", "Processed");
response.Headers.Add("X-Response-Time", DateTime.UtcNow.ToString("O"));
return response;
}
}
// Register ใน WebApiConfig
config.MessageHandlers.Add(new CustomHeaderHandler());
Client-Side Handler Pipeline
// Default: HttpClientHandler (ส่งจริงไป Network)
var client = new HttpClient();
// Custom Pipeline: CustomHandler → HttpClientHandler
var handler = new HttpClientHandler();
var customHandler = new LoggingHandler(handler);
var client = new HttpClient(customHandler);
public class LoggingHandler : DelegatingHandler {
protected override async Task SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken) {
Console.WriteLine($"→ {request.Method} {request.RequestUri}");
var sw = Stopwatch.StartNew();
var response = await base.SendAsync(request, cancellationToken);
sw.Stop();
Console.WriteLine($"← {(int)response.StatusCode} {response.StatusCode} ({sw.ElapsedMilliseconds}ms)");
return response;
}
}
HttpMessageHandler Base Class Hierarchy
HttpMessageHandler (Abstract)
├── DelegatingHandler (Abstract) - สำหรับ Chaining
│ ├── Custom Handlers (User-defined)
│ ├── HttpRoutingDispatcher
│ └── HttpControllerDispatcher
└── HttpClientHandler (Concrete) - Client-side, ส่งจริงไป Network
Use Cases สำหรับ Built-in/Message Handlers
- Authentication/Authorization - Validate Tokens, API Keys
- Logging/Monitoring - Request/Response Logging, Metrics
- Caching - ETag, If-None-Match Handling
- Compression - Gzip/Deflate Request/Response
- Error Handling - Global Exception Handling, Problem Details
- Correlation IDs - Track Requests Across Services
- Rate Limiting - Throttle Requests Per Client