我正在实现一个Web API,当资源不可用时,它将向客户端返回202接受。返回给客户端的URL类似于
http://host/api/v2/**thing**reqests/*guid*
我想一般地这样做,因为我有许多不同类型的资源(因此还有控制器),并且我不想重复代码。
我创建了
[AttributeUsage(AttributeTargets.Class)]
public class RelatedControllerAttribute : Attribute
{
public Type RelatedControllerType { get; }
public RelatedControllerAttribute(Type relatedControllerType) => RelatedControllerType = relatedControllerType;
}
像这样将其应用于主控制器
[RelatedController(typeof(ThingRequestsController))]
public class ThingsController : ApiController<ThingRequest>
这使我可以进入与请求控制器关联的路由模板。
[Route("api/v{version:apiVersion}/[controller]")]
此代码位于ThingsController的基类中
private string GetRequestsRoute()
{
if (_requestsPath != null)
return _requestsPath;
var a = GetType().GetCustomAttribute<RelatedControllerAttribute>();
if (a == null)
throw new NotSupportedException();
var routeTemplate = a.RelatedControllerType.GetCustomAttribute<RouteAttribute>().RouteTemplate;
return _requestsPath = route.Name;
}
这几乎使我到了那里。如何使用正确的有意义值实例化路由模板。 ASP.NET Core中内置了什么吗?我可以轻松地完成路线的[controller]
部分,但是如何做到{version:ApiVersion}
部分(来自ApiExplorer)呢?
答案 0 :(得分:0)
我最终结束了。感觉有些欠佳,但是可以。
private string GetRequestsRoute(string requestsRoot)
{
if (_requestsPath != null)
return _requestsPath;
var relatedControllerAttribute = GetType().GetCustomAttribute<RelatedControllerAttribute>();
if (relatedControllerAttribute == null)
throw new NotSupportedException($"The {GetType().Name} must have a ${typeof(RelatedControllerAttribute).Name}");
var apiExplorerSettingsAttribute = relatedControllerAttribute.RelatedControllerType.GetCustomAttribute<ApiExplorerSettingsAttribute>();
if (apiExplorerSettingsAttribute == null)
throw new NotSupportedException($"The {relatedControllerAttribute.RelatedControllerType.Name} must have a ${typeof(ApiExplorerSettingsAttribute).Name}");
var routeAttribute = relatedControllerAttribute.RelatedControllerType.GetCustomAttribute<RouteAttribute>();
if (routeAttribute == null)
throw new NotSupportedException($"The {relatedControllerAttribute.RelatedControllerType.Name} must have a ${typeof(RouteAttribute).Name}");
return _requestsPath = routeAttribute.Template
.Replace(
"[controller]",
relatedControllerAttribute.RelatedControllerType.Name.Replace("Controller", ""))
.Replace(
"{version:apiVersion}",
apiExplorerSettingsAttribute.GroupName.Replace("v", ""))
.ToLowerInvariant();
}