4

I'm trying to ignore property on swagger UI. based on this article I have implemented a Filter and tried

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class SwaggerExcludeAttribute : Attribute
{
}

public class SwaggerExcludeFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (schema?.Properties == null || context == null) return;
        var excludedProperties = context.Type.GetProperties()
            .Where(t => t.GetCustomAttribute(typeof(SwaggerExcludeAttribute), true) != null);
        foreach (var excludedProperty in excludedProperties)
        {
            if (schema.Properties.ContainsKey(excludedProperty.Name))
                schema.Properties.Remove(excludedProperty.Name);
        }
    }
}
  1. custom attribute seems not properly getting by reflection excludedProperties always empty.
  2. context.MemberInfo does read the property but cannot remove from schema.Properties because no properties there

my sample model is like

public class SequenceSetupListModel
{
    public int Id { get; set; }
    public int Sequence { get; set; }
    public string Role { get; set; }
    public string User { get; set; }
    [SwaggerExclude]
    public IList<Sequence> SequenceLists { get; set; }
}

What I'm missing here

Regards

Gayan
  • 2,750
  • 5
  • 47
  • 88

5 Answers5

7

If you mark the property as internal instead of public then it will be ignored by Swashbuckle.

IronSean
  • 1,520
  • 17
  • 31
4

[JsonIgnore] will just ignore property if the way of model binding is [FromBody] and it does not work for [FromQuery] and [FromForm] use this filter to ignore properties in all binding way

 public class IgnorePropertyFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        if (context.ApiDescription == null || operation.Parameters == null)
            return;

        if (!context.ApiDescription.ParameterDescriptions.Any())
            return;

        
        context.ApiDescription.ParameterDescriptions.Where(p => p.Source.Equals(BindingSource.Form)
                    && p.CustomAttributes().Any(p => p.GetType().Equals(typeof(JsonIgnoreAttribute))))
            .ForAll(p => operation.RequestBody.Content.Values.Single(v => v.Schema.Properties.Remove(p.Name)));



        context.ApiDescription.ParameterDescriptions.Where(p => p.Source.Equals(BindingSource.Query)
                      && p.CustomAttributes().Any(p => p.GetType().Equals(typeof(JsonIgnoreAttribute))))
            .ForAll(p => operation.Parameters.Remove(operation.Parameters.Single(w => w.Name.Equals(p.Name))));


        #region OldCode

        //var excludedProperties = context.ApiDescription.ParameterDescriptions.Where(p =>
        //    p.Source.Equals(BindingSource.Form));

        //if (excludedProperties.Any())
        //{

        //    foreach (var excludedPropertie in excludedProperties)
        //    {
        //        foreach (var customAttribute in excludedPropertie.CustomAttributes())
        //        {
        //            if (customAttribute.GetType() == typeof(JsonIgnoreAttribute))
        //            {
        //                for (int i = 0; i < operation.RequestBody.Content.Values.Count; i++)
        //                {
        //                    for (int j = 0; j < operation.RequestBody.Content.Values.ElementAt(i).Encoding.Count; j++)
        //                    {
        //                        if (operation.RequestBody.Content.Values.ElementAt(i).Encoding.ElementAt(j).Key ==
        //                            excludedPropertie.Name)
        //                        {
        //                            operation.RequestBody.Content.Values.ElementAt(i).Encoding
        //                                .Remove(operation.RequestBody.Content.Values.ElementAt(i).Encoding
        //                                    .ElementAt(j));
        //                            operation.RequestBody.Content.Values.ElementAt(i).Schema.Properties.Remove(excludedPropertie.Name);


        //                        }
        //                    }
        //                }

        //            }
        //        }
        //    }

        //}


        #endregion
    }
}

in startup

services.AddSwaggerGen(options =>
{
    options.OperationFilter<IgnorePropertyFilter>();
});

now [JsonIgnore] will work in all model binding

3

You don't actually need to define own attribute for request models. If you are using Json.NET then use [JsonIgnore]

Roman Marusyk
  • 23,328
  • 24
  • 73
  • 116
2

To all who are wondering why [JsonIgnore] isn't working, its because you cannot use the Newtonsoft library version on .net core 3.x. You need to use the System.Text.Json nuget package. https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/README.md#systemtextjson-stj-vs-newtonsoft

2

There is the [OpenApiIgnore] attribute in the NSwag.Annotations namespace for AspNetCore. It appears to work on a class or a method and excludes them from the generated Swagger document. You will need to include the NSwag.AspNetCore package from NuGet.

BusyBee
  • 219
  • 3
  • 6
  • 1
    Is there concern in using Swashbuckle + NSwag in the same project? Is there overlap in functionality? – fix Mar 15 '22 at 18:30