Удаление маршрута с помощью IOperationFilter в SwashBuckle
Я ищу способ показать / скрыть маршруты WebAPI в документации Swagger, используя SwashBuckle настраиваемым способом. Добавление [ApiExplorerSettings(IgnoreApi = true)]
действительно скроет маршруты, но мне нужно будет перекомпилировать каждый раз, когда я хочу, чтобы это изменилось.
Я посмотрел на создание IOperationFilter
для работы с пользовательским атрибутом, который я определил. Таким образом, я могу украсить маршруты с [SwaggerTag("MobileOnly")]
и проверьте интернет.config или что-то, чтобы увидеть, должен ли отображаться маршрут. Атрибут определяется как такие:
public class SwaggerTagAttribute : Attribute
{
public string[] Tags { get; private set; }
public SwaggerTagAttribute(params string[] tags)
{
this.Tags = tags;
}
}
на IOperationFilter
, который обнаруживает атрибут определяется и IDocumentFilter
который удаляет путь определяется здесь:
public class RemoveTaggedOperationsFilter : IOperationFilter, IDocumentFilter
{
private List<string> TagsToHide;
public RemoveTaggedOperationsFilter()
{
TagsToHide = ConfigurationManager.AppSettings["TagsToHide"].Split(',').ToList();
}
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
{
var tags = apiDescription.ActionDescriptor
.GetCustomAttributes<SwaggerTagAttribute>()
.Select(t => t.Tags)
.FirstOrDefault();
if (tags != null && TagsToHide.Intersect(tags).Any())
{
operation.tags = new List<string> {"Remove Me "};
}
}
public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
{
foreach (var value in swaggerDoc.paths.Values)
{
if (value.post != null && value.post.tags.Contains("Remove Me"))
value.post = null;
if (value.get != null && value.get.tags.Contains("Remove Me"))
value.get = null;
if (value.put != null && value.put.tags.Contains("Remove Me"))
value.put = null;
if (value.delete != null && value.delete.tags.Contains("Remove Me"))
value.delete = null;
}
}
}
зарегистрированы:
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
c.OperationFilter<RemoveTaggedOperationsFilter>();
c.DocumentFilter<RemoveTaggedOperationsFilter>();
});
Я чувствую, что это неэффективно и богатство, чтобы пометить что-то для удаления позже, когда у меня есть доступ к нему раньше. Есть ли способ, которым я просто удаляю маршрут изнутри IOperationFilter.Apply
вместо того, чтобы ждать IDocumentFilter
и сканировать его?
1 ответов
кто-то отправил ответ ранее и сказал, что они отправят код, как только у них будет шанс. Они удалили свой ответ по какой-то причине, но это привело меня к лучшему решению.
вместо IOperationFilter
чтобы пометить маршрут, а затем IDocumentFilter
удалить маршрут вы можете просто использовать IDocumentFilter
чтобы найти пользовательский атрибут и удалить его одним махом. Код ниже:
public class HideTaggedOperationsFilter : IDocumentFilter
{
private List<string> TagsToHide;
public HideTaggedOperationsFilter()
{
TagsToHide = ConfigurationManager.AppSettings["TagsToHide"].Split(',').ToList();
}
public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
{
if (_tagsToHide == null) return;
foreach (var apiDescription in apiExplorer.ApiDescriptions)
{
var tags = apiDescription.ActionDescriptor
.GetCustomAttributes<SwaggerTagAttribute>()
.Select(t => t.Tags)
.FirstOrDefault();
if (tags == null || !_tagsToHide.Intersect(tags).Any())
continue;
var route = "/" + apiDescription.Route.RouteTemplate.TrimEnd('/');
swaggerDoc.paths.Remove(route);
}
}
}
public class SwaggerTagAttribute : Attribute
{
public string[] Tags { get; }
public SwaggerTagAttribute(params string[] tags)
{
this.Tags = tags;
}
}
зарегистрировать IDocumentFilter
:
GlobalConfiguration.Configuration.EnableSwagger(c =>
{
...
c.DocumentFilter<HideTaggedOperationsFilter>();
});
тогда просто украсьте маршрут такой:
[SwaggerTag("MobileOnly")]
public IHttpActionResult SendTest(Guid userId)
{
return OK();
}
Edit:
есть некоторые сообщения о проблемах на странице GitHub для SwashBuckle, которые рекомендуют устанавливать каждый из HTTP-глаголов в null на swaggerDoc.path
на Apply
. Я нашел это, чтобы сломать много генераторов автоматического кода, таких как AutoRest, поэтому я просто удаляю путь в целом. (Он тоже выглядит более лаконичным)