Как я могу вручную создать маршрут на основе атрибутов контроллера? - PullRequest
0 голосов
/ 22 декабря 2018

Я внедряю веб-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)?

1 Ответ

0 голосов
/ 28 декабря 2018

Я закончил с этим.Это кажется немного неоптимальным, но это работает.

    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();
    }
...