如何在ASP.NET Core WeatherForecast示例中配置HttpMessageHandler?
在ASP.NET Core Web API中实现请求/响应拦截
场景1:拦截Web API作为客户端调用外部API的请求/响应(使用HttpMessageHandler)
如果你的MessageHandler1继承自DelegatingHandler,用于拦截当前Web API调用外部API时的请求和响应,按以下步骤配置:
1. 确保Handler的正确结构
你的MessageHandler1需要重写SendAsync方法,示例如下:
public class MessageHandler1 : DelegatingHandler { protected override async Task<HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken) { // 请求发送到外部API前的拦截逻辑(类似WCF的BeforeSendRequest) Console.WriteLine($"准备发送请求到外部API: {request.Method} {request.RequestUri}"); // 可修改请求头、读取请求内容等 // 传递请求到下一个处理环节 var response = await base.SendAsync(request, cancellationToken); // 收到外部API响应后的拦截逻辑(类似WCF的AfterReceiveReply) Console.WriteLine($"收到外部API响应: {response.StatusCode}"); // 可修改响应头、读取响应内容等 return response; } }
2. 在Program.cs中注册Handler
将MessageHandler1注入服务容器,并配置HttpClient时关联该Handler:
var builder = WebApplication.CreateBuilder(args); // 注册自定义Handler builder.Services.AddTransient<MessageHandler1>(); // 配置HttpClient并添加Handler builder.Services.AddHttpClient("ExternalApiClient") .AddHttpMessageHandler<MessageHandler1>(); // 其他服务注册 builder.Services.AddControllers(); // ... var app = builder.Build(); // 中间件配置 app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
3. 在控制器中激活使用
通过IHttpClientFactory创建配置好的HttpClient,Handler会自动生效:
[ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { private readonly IHttpClientFactory _httpClientFactory; public WeatherForecastController(IHttpClientFactory httpClientFactory) { _httpClientFactory = httpClientFactory; } [HttpGet(Name = "GetWeatherForecast")] public async Task<IEnumerable<WeatherForecast>> Get() { // 使用配置好的HttpClient调用外部API var client = _httpClientFactory.CreateClient("ExternalApiClient"); var externalResponse = await client.GetAsync("https://example.com/api/data"); // 处理外部响应... return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), TemperatureC = Random.Shared.Next(-20, 55), Summary = Summaries[Random.Shared.Next(Summaries.Length)] }).ToArray(); } private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; }
场景2:拦截当前Web API接收的请求和发送的响应(类似WCF服务端消息检查器)
如果需要拦截客户端发送到当前Web API的请求(到达控制器前),以及Web API返回给客户端的响应(发送前),推荐使用ASP.NET Core中间件(HttpMessageHandler主要用于客户端请求场景),步骤如下:
1. 编写自定义中间件
public class RequestResponseInterceptorMiddleware { private readonly RequestDelegate _next; public RequestResponseInterceptorMiddleware(RequestDelegate next) { _next = next; } public async Task InvokeAsync(HttpContext context) { // 1. 请求到达控制器前的拦截逻辑 Console.WriteLine($"收到客户端请求: {context.Request.Method} {context.Request.Path}"); // 可读取请求内容、修改请求头、验证请求等 // 保存原始响应流,以便后续读取响应内容 var originalResponseBody = context.Response.Body; using var responseStream = new MemoryStream(); context.Response.Body = responseStream; // 继续执行请求管道,到达控制器处理请求 await _next(context); // 2. 响应发送给客户端前的拦截逻辑 responseStream.Seek(0, SeekOrigin.Begin); var responseContent = await new StreamReader(responseStream).ReadToEndAsync(); Console.WriteLine($"准备发送响应给客户端,状态码: {context.Response.StatusCode},内容: {responseContent}"); // 可修改响应内容、响应头、状态码等 // 将修改后的响应写回原始流 responseStream.Seek(0, SeekOrigin.Begin); await responseStream.CopyToAsync(originalResponseBody); context.Response.Body = originalResponseBody; } }
2. 在Program.cs中注册中间件
将中间件添加到请求管道中,注意注册顺序(通常放在UseAuthorization之后,MapControllers之前):
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); // ...其他服务注册 var app = builder.Build(); app.UseHttpsRedirection(); app.UseAuthorization(); // 注册自定义中间件 app.UseMiddleware<RequestResponseInterceptorMiddleware>(); app.MapControllers(); app.Run();
这样所有发送到当前Web API的请求都会被拦截,响应也会在发送前被处理,完全匹配你需要的WCF消息检查器效果。
内容的提问来源于stack exchange,提问作者codingjoe
相关产品推荐
相关产品推荐

