C
C#2y ago
júlio

❔ IHealthCheck and Swagger

Hello. I'm experimenting with the interface IHealthCheck in my Web Service. I used to have a endpoint that would just return 200OK called /health, but I discovered that there was a Interface for this, and with many functionalities, so I want to try get it working. I followed the documentation (https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/health-checks?view=aspnetcore-7.0) and it kinda works, except Swagger complains a lot. This is what my Controller looks like (the health check part):
[Route("api/[controller]")]
[ApiController]
public class PostalController : ControllerBase, IHealthCheck
{
//...
public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
var isHealthy = true;

// ...

if (isHealthy)
{
return Task.FromResult(HealthCheckResult.Healthy());
}

return Task.FromResult(
new HealthCheckResult(context.Registration.FailureStatus));
}
}
[Route("api/[controller]")]
[ApiController]
public class PostalController : ControllerBase, IHealthCheck
{
//...
public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
var isHealthy = true;

// ...

if (isHealthy)
{
return Task.FromResult(HealthCheckResult.Healthy());
}

return Task.FromResult(
new HealthCheckResult(context.Registration.FailureStatus));
}
}
In Program.cs I have the following code:
builder.Services.AddHealthChecks().AddCheck<PostalController>("Postal Health Check");

//...
app.MapHealthChecks("/healthz", new Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckOptions
{
AllowCachingResponses = false,
ResultStatusCodes =
{
[HealthStatus.Healthy] = StatusCodes.Status200OK,
[HealthStatus.Degraded] = StatusCodes.Status200OK,
[HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable
}
});
builder.Services.AddHealthChecks().AddCheck<PostalController>("Postal Health Check");

//...
app.MapHealthChecks("/healthz", new Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckOptions
{
AllowCachingResponses = false,
ResultStatusCodes =
{
[HealthStatus.Healthy] = StatusCodes.Status200OK,
[HealthStatus.Degraded] = StatusCodes.Status200OK,
[HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable
}
});
When I run the program, I get this message from Swagger: (attached image)
11 Replies
júlio
júlioOP2y ago
Swashbuckle.AspNetCore.SwaggerGen.SwaggerGeneratorException: Ambiguous HTTP method for action - Postal.Controllers.PostalController.CheckHealthAsync (Postal). Actions require an explicit HttpMethod binding for Swagger/OpenAPI 3.0
at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GenerateOperations(IEnumerable`1 apiDescriptions, SchemaRepository schemaRepository)
at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GeneratePaths(IEnumerable`1 apiDescriptions, SchemaRepository schemaRepository)
at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GetSwaggerDocumentWithoutFilters(String documentName, String host, String basePath)
at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GetSwaggerAsync(String documentName, String host, String basePath)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
Swashbuckle.AspNetCore.SwaggerGen.SwaggerGeneratorException: Ambiguous HTTP method for action - Postal.Controllers.PostalController.CheckHealthAsync (Postal). Actions require an explicit HttpMethod binding for Swagger/OpenAPI 3.0
at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GenerateOperations(IEnumerable`1 apiDescriptions, SchemaRepository schemaRepository)
at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GeneratePaths(IEnumerable`1 apiDescriptions, SchemaRepository schemaRepository)
at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GetSwaggerDocumentWithoutFilters(String documentName, String host, String basePath)
at Swashbuckle.AspNetCore.SwaggerGen.SwaggerGenerator.GetSwaggerAsync(String documentName, String host, String basePath)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
This is the Log I get. If I add a [HttpGet("/healthz")] to the Health Check in the Controller, Swagger stops complaining but the behaviour of the endpoint is very weird.
júlio
júlioOP2y ago
júlio
júlioOP2y ago
It has this huge JSON that I have no clue what it's doing there.
júlio
júlioOP2y ago
If I try to access the endpoint manually I get this:
júlio
júlioOP2y ago
Any idea of what is going on?
Tvde1
Tvde12y ago
when you do
services.AddSwaggerGen(options =>
{

});
services.AddSwaggerGen(options =>
{

});
(which is responsible for making the json file) it's possible to change a lot by calling methods on the options. You might be able to exclude these endpoints, or add a default "HttpMethod binding" this is the direction I would search in, not sure how to completely fix your issue I think it's complaining that the public method on your controller, does not have a [HttpGet] or post or so you could add a "IActionModelConvention" to the swagger pipeline that looks like:
public class ApiExplorerConvention : IActionModelConvention
{
public void Apply(ActionModel action)
{
action.ApiExplorer.IsVisible = action.Name = "CheckHealthAsync";
}
}
public class ApiExplorerConvention : IActionModelConvention
{
public void Apply(ActionModel action)
{
action.ApiExplorer.IsVisible = action.Name = "CheckHealthAsync";
}
}
Not sure if that fixes it (or if the name is a valid property) Taken from https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/2031#issuecomment-785384452
júlio
júlioOP2y ago
Stack Overflow
How to omit methods from Swagger documentation on WebAPI using Swas...
I have a C# ASP.NET WebAPI application with API documentation being automatically generated using Swashbuckle. I want to be able to omit certain methods from the documentation but I can't seem to ...
júlio
júlioOP2y ago
I can add [ApiExplorerSettings(IgnoreApi = true)] to the endpoints I want to exclude and everyone is happy I think Atleast I tested and it behaves as expected Thank you for your suggestion!
Tvde1
Tvde12y ago
Perfect!
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.

Did you find this page helpful?