How to configure Swashbuckle to ignore property on model

后端 未结 15 1709
旧巷少年郎
旧巷少年郎 2020-12-02 15:10

I\'m using Swashbuckle to generate swagger documentation\\UI for a webapi2 project. Our models are shared with some legacy interfaces so there are a couple of properties I

相关标签:
15条回答
  • 2020-12-02 15:48

    For people like me who are using .Net Core and are using the build in app.UseSwaggerUi3WithApiExplorer()

    Use [JsonIgnore] tag using Newtonsoft.Json;

    public class Project
    {
        [Required]
        public string ProjectName { get; set; }
    
        [JsonIgnore]
        public string SomeValueYouWantToIgnore { get; set; }
    }
    

    It will be excluded from your documentation.

    0 讨论(0)
  • 2020-12-02 15:50

    Here is what I used with Newtonsoft.Json.JsonIgnoreAttribute:

    internal class ApplySchemaVendorExtensions : Swashbuckle.Swagger.ISchemaFilter
    {
        public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type)
        {
            foreach (var prop in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)
                                     .Where(p => p.GetCustomAttributes(typeof(Newtonsoft.Json.JsonIgnoreAttribute), true)?.Any() == true))
                if (schema?.properties?.ContainsKey(prop.Name) == true)
                    schema?.properties?.Remove(prop.Name);
        }
    }
    
    0 讨论(0)
  • 2020-12-02 15:51

    In my case I wanted to keep my Application Layer DTOs clean (without any annotation like JsonIngore) but still being able to use them in my Controllers Web APIs.

    So, in my Application Layer I have a DTO like this:

    public class CreateItemCommand {
         public Guid ContainerId { get; set; }
         public string Name { get; set; }
    }
    

    And my API design for creating an item is something like: POST /containers/{containerId}/items

    As the ContainerId is coming from the api route, I don't want the asp.net core trying to bind it into the command DTO and I don't want swashbuckle listing it neither.

    So my solution is to inherit the original DTO in the API layer like this:

    public class CreateItemCommandMod : CreateItemCommand {
       #pragma warning disable IDE0051
       private new ContainerID { get; }
       #pragma warning restore IDE0051
    }
    
    ...
    
    [HttpPost("{containerId}/items}")]
    public Task Create(
       [FromRoute] Guid containerId,
       [FromBody] CreateItemCommandMod command,
    ) => useCase.Create(command.Apply(r => r.ContainerId = containerId));
    
    • The useCase.Create from the ApplicationLayer expects the base class CreateItemCommand.
    • .Apply is just a very simple extension method that i've made to easily set the routing parameter value into the correspondent dto property.
    0 讨论(0)
  • 2020-12-02 15:52

    Swashbuckle now has support for Newtonsoft. https://github.com/domaindrivendev/Swashbuckle.AspNetCore#systemtextjson-stj-vs-newtonsoft

    dotnet add package --version 5.3.1 Swashbuckle.AspNetCore.Newtonsoft
    
    `services.AddSwaggerGenNewtonsoftSupport(); // explicit opt-in - needs tobe placed after AddSwaggerGen();`
    
    0 讨论(0)
  • 2020-12-02 15:54

    If you mark field/property as internal or protected or private, it will be ignored automatically by swashbuckle in swagger documentation.

    Update: Obviously, those properties/fields won't be populated in request/response.

    0 讨论(0)
  • 2020-12-02 15:54

    Well, with a bit of poking I found a way to do this using ISchemaFilter:

    public class ApplyCustomSchemaFilters : ISchemaFilter
    {
        public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type)
        {
            var excludeProperties = new[] {"myProp1", "myProp2", "myProp3"};
    
            foreach(var prop in excludeProperties)
                if (schema.properties.ContainsKey(prop))
                    schema.properties.Remove(prop);
        }
    }
    

    then when calling httpConfiguration.EnableSwagger I set the SwaggerDocsConfig to use this SchemaFilter as follows:

    c.SchemaFilter<ApplyCustomSchemaFilters>();
    

    Hope this helps someone. I'd still be curious on whether it's possible to use the IModelFilter somehow though.

    0 讨论(0)
提交回复
热议问题