2

I am working on .Net 5 Web API and I am using Swashbuckle, when I used [JsonIgnore] on my model it works fine for rendering my JSON

Model :

    public partial class ApplicationDocument : BaseModel
    {
        public int id { get; set; }
        public int document_id { get; set; }
        public int application_id { get; set; }
        [NotMapped]
        public string name { get; set; }
        [NotMapped]
        public string documentUrl { get; set; }
        [JsonIgnore]
        public virtual Application application { get; set; }
        [JsonIgnore]
        public virtual Document document { get; set; }
    }

JSON

{
  "applicationDocument": {
    "dateCreated": "2021-05-17T13:08:08.934Z",
    "dateModified": "2021-05-17T13:08:08.934Z",
    "createdBy": "string",
    "modifiedBy": "string",
    "isActive": true,
    "isDeleted": true,
    "id": 0,
    "document_id": 0,
    "application_id": 0,
    "name": "string",
    "documentUrl": "string"
  },
  "fileDocument": "string"
}

the problem is when I used the [FromForm] attribute with my controller, the [JsonIgnore] didn't work for me and it rendered every single field even the navigation fields

Controller

        [HttpPost]
        [Route("[controller]/AddApplicationDocument")]
        public BaseResponse AddApplicationDocument([FromForm] ApplicationDocumentViewModel ApplicationDocumentViewModel)
        {
            return _ApplicationDocument.AddApplicationDocument(ApplicationDocumentViewModel);
        }

Showing Like this

esamaldin elzain
  • 320
  • 1
  • 4
  • 16
  • Does this answer your question? [How to configure Swashbuckle to ignore property on model](https://stackoverflow.com/questions/41005730/how-to-configure-swashbuckle-to-ignore-property-on-model) – gunr2171 May 17 '21 at 13:17
  • not that much, he wants to ignore it without the attribute, but i am using it already and it doesn't work – esamaldin elzain May 17 '21 at 13:18
  • Can you elaborate how it doesn't work for you? One of the answers says to "Use JsonIgnore from System.Text.Json.Serialization namespace. JsonIgnore from Newtonsoft.Json will NOT work." – gunr2171 May 17 '21 at 13:20
  • when it's a normal post it works fine, when it's a [FromForm] post (multipart) form submit it doesn't work - see the attached image – esamaldin elzain May 17 '21 at 13:27
  • 1
    I think you need the `[BindNever]` attribute when using `[FromForm]`. – Kirk Larkin May 17 '21 at 13:30

1 Answers1

0

I have one idea for you, I hope you solve your problem with it.

First , Create this Attribute :

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class SwaggerIgnoreAttribute : Attribute
{
}

Then , Create a OperationFilter and a SchemaFilter for swagger options :

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;


            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(SwaggerIgnoreAttribute))
                        {
                            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);


                                    }
                                }
                            }

                        }
                    }
                }

            }
        }
    }
public class SwaggerIgnoreFilter : ISchemaFilter
    {
        public void Apply(OpenApiSchema schema, SchemaFilterContext schemaFilterContext)
        {
            if (schema.Properties.Count == 0)
                return;

            const BindingFlags bindingFlags = BindingFlags.Public |
                                              BindingFlags.NonPublic |
                                              BindingFlags.Instance;
            var memberList = schemaFilterContext.Type // In v5.3.3+ use Type instead
                                .GetFields(bindingFlags).Cast<MemberInfo>()
                                .Concat(schemaFilterContext.Type // In v5.3.3+ use Type instead
                                .GetProperties(bindingFlags));

            var excludedList = memberList.Where(m =>
                                                m.GetCustomAttribute<SwaggerIgnoreAttribute>()
                                                != null)
                                         .Select(m =>
                                             (m.GetCustomAttribute<JsonPropertyAttribute>()
                                              ?.PropertyName
                                              ?? m.Name.ToCamelCase()));

            foreach (var excludedName in excludedList)
            {
                if (schema.Properties.ContainsKey(excludedName))
                    schema.Properties.Remove(excludedName);
            }
        }

    }

Then , Add both of them for swagger configuration in startup class :

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

Finally, you can use [SwaggerIgnore] for each of properties that you wont to see in swagger :

public partial class ApplicationDocument : BaseModel
{
    public int id { get; set; }
    public int document_id { get; set; }
    public int application_id { get; set; }
        
    public string name { get; set; }
        
    public string documentUrl { get; set; }

    [SwaggerIgnore]
    public virtual Application application { get; set; }
    [SwaggerIgnore]
    public virtual Document document { get; set; }
}
Mohsen Saniee
  • 204
  • 2
  • 17