如何获取控制器和动作的摘要



我正在实现IApiDescriptionGroupCollectionProvider来获取API描述。

我已经这样实现了


private readonly IApiDescriptionGroupCollectionProvider _apiExplorer;
public RouteController(
IApiDescriptionGroupCollectionProvider apiExplorer)
{
_apiExplorer = apiExplorer;
}
[HttpGet("all")]
public IActionResult GetRoute()
{
var paths = GetApiDescriptionsFor("v1");
return Ok();
}

我想将控制器的所有细节绑定到带有动作描述的ApiRouteDocument自定义模型。但是我所实现的接口并没有给出actioncontroller的总结。是否有任何内置接口从操作中提取摘要?

我想避免反射。


[ApiController]
[Route("api/contact")]
[ApiExplorerSettings(GroupName = "Contact")]
public class ContactController : ControllerBase
{
/// <summary>  
/// Get by Name Contact  
/// </summary> 
[HttpGet("getbyname/{name}")]
public async Task<IActionResult> GetByName(string name)
{
return Ok();
}
}
public class ApiRouteDocument
{
//controllername tag
public string ControllerName { get; set; }
public string ControllerDescription { get; set; }
public IList<RoutePath> Paths;
}
public class RoutePath
{
//get
public string Method { get; set; }
//operationid
public string Name { get; set; }
//summary
public string Description { get; set; }
//path
public string Path { get; set; }
}

您必须在中间件管道已经建立(并且app.UseEndpoints()已经执行)之后运行此代码,因此它应该在控制器或端点中运行,例如。

因为文档注释不包括在程序集中,你需要使用属性来注释你的类&行动。您可以选择使用Microsoft提供的名称空间,例如System.ComponentModel.Primitives名称空间下的[DisplayName][Description]等。

或者你可以创建自己的属性:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
internal class SummaryAttribute : Attribute
{
public string Summary { get; }
public SummaryAttribute(string summary)
{
Summary = summary;
}
}

然后在控制器中注入IEnumerable<EndpointDataSource>,这将为您提供发现的端点列表。

你可以从ControllerActionDescriptor中得到反映的运行时类型信息,然后提取你添加到控制器的属性&行动。

[Description("Provides info")]
[Route("info")]
public class ThingsController : ControllerBase
{
private IEnumerable<EndpointDataSource> _endpointDataSources;
public ThingsController(IEnumerable<EndpointDataSource> endpointDataSources)
{
_endpointDataSources = endpointDataSources;
}
[Description("Returns a list of endpoints")]
[HttpGet("endpoints")]
public ActionResult Endpoints()
{
var actions = _endpointDataSources.SelectMany(it => it.Endpoints)
.OfType<RouteEndpoint>()
.Where(
it => it.Metadata
.OfType<ControllerActionDescriptor>()
.Any()
)
.Select(
e => {
var actionDescriptor = e.Metadata
.OfType<ControllerActionDescriptor>()
.First();
var isControllerIgnored = actionDescriptor.ControllerTypeInfo.GetCustomAttribute<ApiExplorerSettingsAttribute>()?.IgnoreApi ?? false;
var isActionIgnored = actionDescriptor.MethodInfo                       .GetCustomAttribute<ApiExplorerSettingsAttribute>()?.IgnoreApi ?? false;
return new
{
ControllerName = actionDescriptor.ControllerName,
ControllerType = actionDescriptor.ControllerTypeInfo.FullName,
ActionDescription = actionDescriptor.MethodInfo.GetCustomAttribute<DescriptionAttribute>()?.Description,
ControllerDescription = actionDescriptor.ControllerTypeInfo
.GetCustomAttribute<DescriptionAttribute>()
?.Description,
Method = actionDescriptor.EndpointMetadata.OfType<HttpMethodMetadata>()
.FirstOrDefault()
?.HttpMethods?[0],
Path = $"/{e.RoutePattern!.RawText!.TrimStart('/')}",
};
}
)
.ToList();
return Ok(actions);
}
}

当您访问/info/endpoints时,您将获得端点列表:

[
{
"controllerName": "Things",
"controllerType": "ApiPlayground.ThingsController",
"actionDescription": "Returns a list of endpoints",
"controllerDescription": "Provides info",
"method": "GET",
"path": "/info/endpoints"
}
]

最新更新