是否有 API 可以从 [路由前缀] 和 [路由] 属性构建 WebAPI 路由
本文关键字:路由 属性 构建 WebAPI 前缀 是否 API | 更新日期: 2023-09-27 18:30:52
我有一个WebApi应用程序,其中包含一堆带有[RoutePrefix]
和[Route]
属性标记的控制器和方法。我想通过反射收集所有这些方法,并使用服务器支持的所有 WebApi 调用通知客户端。
我的目标是通知前端登录用户的可用 API 列表,以便前端可以隐藏不允许的方法的控件。
我写了一个简单的代码来完成这项工作。
// GET api/systeminfo/allowedapi
[HttpGet]
[Route("allowedapi")]
[ResponseType(typeof(WebApiCollectionDto))]
public async Task<IHttpActionResult> GetAllowedApi()
{
List<string> apiList = new List<string>();
Type baseControllerType = typeof(ApiController);
IEnumerable<Type> controllerTypes = GetType().Assembly.GetTypes().Where(item => baseControllerType.IsAssignableFrom(item));
foreach (Type controllerType in controllerTypes)
{
RoutePrefixAttribute routePrefixAttribute = controllerType.GetCustomAttribute<RoutePrefixAttribute>();
IEnumerable<MethodInfo> apiMethods = controllerType.GetMethods();
foreach (MethodInfo apiMethod in apiMethods)
{
RouteAttribute routeAttribute = apiMethod.GetCustomAttribute<RouteAttribute>();
if (routeAttribute == null) // not an api method
continue;
string routeTemplate = routeAttribute.Template;
if (routeTemplate.StartsWith("~"))
apiList.Add(routeTemplate.Substring(1));
else
apiList.Add(String.Format("/{0}/{1}", routePrefixAttribute.Prefix, routeTemplate));
}
}
WebApiCollectionDto result = new WebApiCollectionDto(apiList);
return await Task.FromResult(Ok(result));
}
我担心的是这种实现有点幼稚。为了使此代码可用于生产,我需要在模板的开头和结尾为"/"字符编写额外的处理。那么,是否有一个我可以开箱即用的实现?
谢谢。
有来自Miscrosoft的API可以完成这项工作。 System.Web.Http.Description.IApiExplorer
ASP.NET Web API:介绍 IApiExplorer/ApiExplorer
以及上面代码的更简洁的实现:
// GET api/systeminfo/allowedapi
[HttpGet]
[Route("allowedapi")]
[ResponseType(typeof (WebApiCollectionDto))]
public async Task<IHttpActionResult> GetAllowedApi()
{
List<string> apiList = new List<string>();
IApiExplorer apiExplorer = Configuration.Services.GetApiExplorer();
foreach (ApiDescription apiDescription in apiExplorer.ApiDescriptions)
apiList.Add(apiDescription.RelativePath);
WebApiCollectionDto result = new WebApiCollectionDto(apiList);
return await Task.FromResult(Ok(result));
}