Files
LaDOSE/LaDOSE.Src/LaDOSE.Api/Helpers/ApiExplorerVisibilityConvention.cs
T

42 lines
1.7 KiB
C#

#if DEBUG
using System.Linq;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.Routing;
namespace LaDOSE.Api.Helpers
{
/// <summary>
/// The controllers in this project are attribute-routed but do not carry [ApiController].
/// Without it MVC never sets ApiExplorer visibility, so ApiExplorer yields no descriptions
/// and the generated OpenAPI document comes out with an empty "paths" object.
/// This convention opts the attribute-routed actions into ApiExplorer for the
/// OpenAPI/Scalar tooling only, without pulling in the [ApiController] behaviours
/// (automatic 400 responses, [FromBody] inference) that would change runtime binding.
/// </summary>
public class ApiExplorerVisibilityConvention : IControllerModelConvention
{
public void Apply(ControllerModel controller)
{
// Default the controller to hidden, then opt in action by action.
controller.ApiExplorer.IsVisible ??= false;
foreach (var action in controller.Actions)
{
if (action.ApiExplorer.IsVisible != null)
{
continue;
}
// An action with a [Route] but no verb attribute (e.g. BotEventController's
// CreateBotEvent) matches every HTTP method, so ApiExplorer reports an empty
// method and OpenAPI generation throws "Unsupported HTTP method".
// Only document actions that pin down a verb.
action.ApiExplorer.IsVisible = action.Attributes
.OfType<IActionHttpMethodProvider>()
.Any(provider => provider.HttpMethods?.Any() == true);
}
}
}
}
#endif