Swashbuckle隐藏未引用的模型

时间:2017-09-08 12:24:34

标签: swashbuckle

我在隐藏调用时遇到了Swashbuckle的问题,链接到调用的模型的定义仍保留在生成的JSON中的定义中。

使用文档过滤器,我可以从界面中删除呼叫。

调用保留在生成的JSON中,但在Swagger UI中不可见。 我们还可以看到模型和枚举的定义与这些调用相关联。

这些是内部调用,需要在JSON中隐藏外部眼睛。

如何隐藏所有通话及其参考?

使用[ApiExplorerSettings(IgnoreApi = true)]可以解决我的问题,但我需要使用现有属性进行过滤。

1 个答案:

答案 0 :(得分:3)

所以我通过努力找到了问题的答案。 我把它放在这里,以便我的问题的下一个人会比我更好。

public static class SwashbuckleExtensions
{
    public static IEnumerable<Operation> EnumerateOperations(this PathItem pathItem)
    {
        if (pathItem == null)
        {
            yield break;
        }
        yield return pathItem.get;
        yield return pathItem.post;
        yield return pathItem.put;
        yield return pathItem.delete;
        yield return pathItem.options;
        yield return pathItem.head;
    }


    public static IEnumerable<Schema> EnumerateSchema(this Operation operation)
    {
        if (operation == null)
        {
            yield break;
        }
                   foreach (var response in operation.responses ?? new Dictionary<string, Response>())
        {
            yield return response.Value.schema;
            if (response.Value.schema.items != null)
            {
                yield return response.Value.schema.items;
            }
        }
        foreach (var parameter in operation.parameters ?? new List<Parameter>())
        {
            yield return parameter.schema;
        }
    }


    public static IEnumerable<Schema> FindAdditionalSchema(this Schema schema, IDictionary<string, Schema> listOfDefinition)
    {
        if (!string.IsNullOrEmpty(schema.@ref))
        {
            Schema definition;
            if (listOfDefinition.TryGetValue(schema.@ref.Replace("#/definitions/", String.Empty), out definition))
            {
                foreach (var propertySchema in definition.properties)
                {
                    yield return propertySchema.Value;
                }
            }
        }
        if (!string.IsNullOrEmpty( schema?.items?.@ref))
        {
            Schema definition;
            if (listOfDefinition.TryGetValue(schema.items.@ref.Replace("#/definitions/", String.Empty), out definition))
            {
                foreach (var propertySchema in definition.properties)
                {
                    yield return propertySchema.Value;
                }
            }
        }
    }

    public static IEnumerable<Schema> EnumerateSchema(this Schema schema,IDictionary<string,Schema> listOfDefinition, int dept = 0)
    {
        if (schema == null)
        {
            yield break;
        }
        if (dept > 10)
        {
            yield break;
        }
        if (dept == 0)
        {
            yield return schema;
        }

        var ListOfAdditionalSchema = schema.FindAdditionalSchema(listOfDefinition) ?? new List<Schema>();
        foreach (var additionalSchema in ListOfAdditionalSchema)
        {
            yield return additionalSchema;
            foreach (var childSchema in additionalSchema.EnumerateSchema(listOfDefinition,dept++) ?? new List<Schema>())
            {
                yield return childSchema;
            }
        }
       }
}

然后在DocumentFilter

    public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
        {


            foreach (var value in swaggerDoc.paths.Values)
            {
                if (value.post != null && value.post.tags.Contains(ToHide))
                    value.post = null;

                if (value.get != null && value.get.tags.Contains(ToHide))
                    value.get = null;

                if (value.put != null && value.put.tags.Contains(ToHide))
                    value.put = null;

                if (value.delete != null && value.delete.tags.Contains(ToHide))
                    value.delete = null;

                if (value.head != null && value.head.tags.Contains(ToHide))
                    value.head = null;

                if (value.options != null && value.options.tags.Contains(ToHide))
                    value.options = null;
            }

            var pathToDelete = swaggerDoc.paths.Where(x => !x.Value.EnumerateOperations().Any(y=>y != null) )
                                               .ToList();//Deleting item from source need list 
            foreach (var item in pathToDelete)
            {
                swaggerDoc.paths.Remove(item.Key);
            }


            var listOfSchemaWithReference = swaggerDoc.paths.SelectMany(x => x.Value.EnumerateOperations())//Find operation by path
                                            .SelectMany(x => x.EnumerateSchema()) //Find schema by operation
                                            .SelectMany(x => x.EnumerateSchema(swaggerDoc.definitions))//Find Schema by schema (dependent schema)
                                            .Where(x=> x?.@ref != null || x?.items?.@ref != null)//I only wany the schema that reference a definition.
                                            .Select(x=> ((x?.@ref) ?? (x.items?.@ref) ).Replace("#/definitions/", String.Empty))//remove the path and keep the Model name
                                            .Distinct()//I dont like duplicates
                                            .ToList();//commit to memory

            //Not finding a definition in the built list of reference means its unreferenced and can be removed.
            var listOfUnreferencedDefinition = swaggerDoc.definitions.Where(x => !listOfSchemaWithReference.Any(y => y == x.Key))
                                                                     .ToList();//Deleting item from source need list 

            foreach (var unreferencedDefinition in listOfUnreferencedDefinition)
            {
                swaggerDoc.definitions.Remove(unreferencedDefinition.Key);
            }
        }
    }