Swashbuckle Hide unreferenced model

时光毁灭记忆、已成空白 提交于 2020-04-11 08:48:07

问题


I'm having a problem with Swashbuckle when hiding a call the definition of the model linked to the call remains in the definition in the JSON generated.

Using the Document filter, I'm able to remove the call from the interface.

The calls remain in the JSON generated but are invisible in Swagger UI. We can also see the definition for the Model and Enum linked to theses calls.

Theses are internal calls and need to be hidden from external eyes in the JSON.

How can I hide all the calls and their references?

Using [ApiExplorerSettings(IgnoreApi = true)] would fix my problem but I need to filter with an existing attribute.


回答1:


So I found the answer to my question through hard work. I'm putting it here so that the next person with my issue will have a nicer time then me.

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;
            }
        }
       }
}

Then in the 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);
            }
        }
    }


来源:https://stackoverflow.com/questions/46116507/swashbuckle-hide-unreferenced-model

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!