Azure Function中AspNetCore.HealthCheck异常时始终返回200问题
我们有一个基于.NET Core 7的Azure Function,已集成AspNetCore.HealthCheck功能。当健康检查判定状态为不健康时,我们返回ServiceUnavailableObjectResult实例,但无论返回何种结果,HTTP状态码始终为200。
相关代码
Program.cs 健康检查配置
services.AddHealthChecks() .AddUrlGroup( uri: new Uri($"{baseAddress}/health"), name: "Mgmt") .AddAzureBlobStorage( connectionString: context.Configuration.GetValue<string>(RecipientUploadOptions.BlobConnectionStringName), containerName: context.Configuration.GetValue<string>(RecipientUploadOptions.IncomingContainerName), name: "IncomingBlobContainer") .AddAzureBlobStorage( connectionString: context.Configuration.GetValue<string>(RecipientUploadOptions.BlobConnectionStringName), containerName: context.Configuration.GetValue<string>(RecipientUploadOptions.ErrorContainerName), name: "ErrorBlobContainer") .AddAzureBlobStorage( connectionString: context.Configuration.GetValue<string>(RecipientUploadOptions.BlobConnectionStringName), containerName: context.Configuration.GetValue<string>(RecipientUploadOptions.ArchiveContainerName), name: "ArchiveBlobContainer");
HealthCheckFunction.cs 健康检查函数
[Function("health")] public async Task<IActionResult> Health([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData z) { var status = await _healthCheckService.CheckHealthAsync(); if (status.Status == HealthStatus.Healthy) { return new OkObjectResult(Enum.GetName(typeof(HealthStatus), status.Status)); } return new ServiceUnavailableObjectResult(Enum.GetName(typeof(HealthStatus), status.Status)); }
预期与实际结果
- 预期:返回HTTP状态码503 - Service Unavailable及对应响应内容
- 实际:始终返回HTTP状态码200 - OK,但响应体显示503错误结果;相同代码在Web API项目中可正常返回503状态码
解决方案
Azure Functions的HttpRequestData触发器与Web API的HttpContext处理逻辑不同,直接返回IActionResult不会自动映射状态码,需通过以下方式解决:
方案1:直接构建HttpResponseData返回(最简)
放弃IActionResult,手动创建响应并设置状态码:
[Function("health")] public async Task<HttpResponseData> Health([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req) { var status = await _healthCheckService.CheckHealthAsync(); var response = req.CreateResponse(); var statusText = Enum.GetName(typeof(HealthStatus), status.Status); await response.WriteStringAsync(statusText); response.StatusCode = status.Status == HealthStatus.Healthy ? HttpStatusCode.OK : HttpStatusCode.ServiceUnavailable; return response; }
方案2:适配IActionResult到HttpResponseData
若需保留IActionResult的使用,可通过IActionResultExecutor手动执行结果映射:
- 注入依赖到函数类:
private readonly IHealthCheckService _healthCheckService; private readonly IActionResultExecutor<ObjectResult> _resultExecutor; public HealthCheckFunction(IHealthCheckService healthCheckService, IActionResultExecutor<ObjectResult> resultExecutor) { _healthCheckService = healthCheckService; _resultExecutor = resultExecutor; }
- 修改函数逻辑:
[Function("health")] public async Task<HttpResponseData> Health([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req) { var status = await _healthCheckService.CheckHealthAsync(); ObjectResult result = status.Status == HealthStatus.Healthy ? new OkObjectResult(Enum.GetName(typeof(HealthStatus), status.Status)) : new ServiceUnavailableObjectResult(Enum.GetName(typeof(HealthStatus), status.Status)); var actionContext = new ActionContext(req.HttpContext, new RouteData(), new Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor()); await _resultExecutor.ExecuteAsync(actionContext, result); return req.CreateResponse(req.HttpContext.Response.StatusCode); }
方案3:使用Azure Functions原生健康检查(推荐)
Azure Functions自带原生健康检查功能,无需自定义函数:
- 在
host.json中启用配置:
{ "healthChecks": { "enabled": true, "path": "/health" } }
- 系统会自动暴露
/health端点,根据健康检查结果返回对应状态码(健康返回200,不健康返回503),无需手动编写逻辑。
内容的提问来源于stack exchange,提问作者amber
相关产品推荐
相关产品推荐

