Closed syaifulnizamyahya closed 4 years ago
@yahyanajar It doesn't work. It still show ignored properties with [JsonIgnore] in request model on get actions. @syaifulnizamyahya did you resolve this issue?
[JsonIgnore]
internal string CountryCode { get; set; }
This works for me.
JsonIgnore doesn't work for me
Use the [DataContract] for the model and use [DataMember] for the properties which you want to show in Swagger. Any property which isn't marked as [DataMember] doesn't show up in your swagger definition. Let me know if this works or not.
None of the methods above work for me. I am using .NET Core 2.2.
I've solved this issue before. You can create a custom attribute, then make a SchemaFilter that detects that attribute and removes the property from the Schema model.
Have you tried [Obsolete]
?
[JsonIgnore] seems to be a more natural choice for this feature.
[JsonIgnore] seems to be a more natural choice for this feature.
That prevents it from being serialized. [Obsolete] allows serialization but prevents it from showing in the swagger output (and can trigger warnings when you reference it, which in my case is what I want, as the field is intended to be phased out but I wish to keep for backward-compatibility purposes in the meantime).
In FromQuery case, JsonIgnore is not working. Is there other tag we could use? Obsolete is not suitable, as it's not phase out. Doesn't have to be system attribute, does swagger provide any custom tag for this purpose?
@arisliang Please check and try out my answer above, it's working for me.
None of the methods above work for me. I am using .NET Core 2.2.
- [DataContract] ends up showing all members anyway
- marking attribute as 'internal' or [JsonIgnore] doesn't deserialize the property if manually added in swaggerUI
This works for .net core 3.0 also.
In the end, DataContract and DataMember worked for us.
Guys, we are having the same problem on net Core 3.1.10 Swashbuckle.AspNetCore.Swagger -Version 5.0.0-rc4 is working fine! Swashbuckle.AspNetCore.Swagger -Version 5.0.0 stopped working...
Swagger is not respecting "[DataMember]" for displaying or not properties on [DataContract] classes. Hidden properties were shown either. Did something change? The stable release is not working as well.
Same with JsonIgnore and/or IgnoreDataMember, works up to -rc4
I'm using .net core 3.1, using the [JsonIgnore] from System.Text.Json.Serialization works. (if it used from NewtonSoft.Json, it doesn't!)
I added "services.AddSwaggerGenNewtonsoftSupport(); // explicit opt-in - needs to be placed after AddSwaggerGen()", but it still doesn't respect newtonsoft JsonIgnore. I'm using core 2.1, and Swashbuckle 5.1
Thank you @shankarab, your solution works.
@shankarab "I'm using .net core 3.1, using the [JsonIgnore] from System.Text.Json.Serialization works. (if it used from NewtonSoft.Json, it doesn't!)"
Thanks for your answer. it work's for me.
JsonIgnore doesn't work for me
me as well
I added "services.AddSwaggerGenNewtonsoftSupport(); // explicit opt-in - needs to be placed after AddSwaggerGen()", but it still doesn't respect newtonsoft JsonIgnore. I'm using core 2.1, and Swashbuckle 5.1
I'm using .net core 3.1, using the [JsonIgnore] from System.Text.Json.Serialization works. (if it used from NewtonSoft.Json, it doesn't!)
Yes this helps I was using JsonIgnore from "Newtonsoft.Json"
[JsonIgnore] will work if the property is in the request's body, as it prevents it from being deserialized. If the property comes from the query string, it will not work.
In that case you could use [BindNever] from Microsoft.AspNetCore.Mvc.ModelBinding, this will make the model binder ignore that property and it will no longer be shown in swagger.
If using .netcore below v3 and Swashbuckle 5.xxx either add services.AddSwaggerGenNewtonsoftSupport() or downgrade to Swashbuckle 4.xxx. If on .netcore 3 then use Swashbuckle 5.xxx and ensure you reference [JsonIgnore] from System.Text.Json.Serialization and not NewtonSoft.Json. This is because .netcore v3+ no longer uses NewtonSoft.Json as default
FWIW, I wanted to do this for the request parameter and non of the above worked. I had to make my properties internal
and that did the trick
You my create a new [SwaggerIgnore]
attribute to use that anywhere in your class. Something similar JsonIgnore
, but for Swagger UI
Create a attribute
SwaggerIgnoreAttribute.cs
using System;
namespace TestApi.Attributes
{
public class SwaggerIgnoreAttribute : Attribute
{
}
}
Create a filter
SwaggerSkipPropertyFilter.cs
using Microsoft.OpenApi.Models;
using TestApi.Attributes;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Reflection;
namespace TestApi.Filters
{
public class SwaggerSkipPropertyFilter : ISchemaFilter
{
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
if (schema?.Properties == null)
{
return;
}
var skipProperties = context.Type.GetProperties().Where(t => t.GetCustomAttribute<SwaggerIgnoreAttribute>() != null);
foreach (var skipProperty in skipProperties)
{
var propertyToSkip = schema.Properties.Keys.SingleOrDefault(x => string.Equals(x, skipProperty.Name, StringComparison.OrdinalIgnoreCase));
if (propertyToSkip != null)
{
schema.Properties.Remove(propertyToSkip);
}
}
}
}
}
Add to Startup.cs
Startup.cs
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Test API", Version = "v1" });
c.SchemaFilter<SwaggerSkipPropertyFilter >();
});
Use in your class
public class User
{
[SwaggerIgnore]
public long user_id { get; set; }
}
Latest version, [JsonIgnore]
is working fine, just make sure you have the correct one, or add both to be sure :)
[System.Text.Json.Serialization.JsonIgnore]
[Newtonsoft.Json.JsonIgnore]
Latest version,
[JsonIgnore]
is working fine, just make sure you have the correct one, or add both to be sure :)[System.Text.Json.Serialization.JsonIgnore] [Newtonsoft.Json.JsonIgnore]
Yes but as mentioned above, that prevents the property from being serialized at all.
I'm using .net core 3.1, using the [JsonIgnore] from System.Text.Json.Serialization works. (if it used from NewtonSoft.Json, it doesn't!)
This doesn't work in a scenario where you derive from a class and have a property with the "new" keyword to hide the base property.
Latest version,
[JsonIgnore]
is working fine, just make sure you have the correct one, or add both to be sure :)[System.Text.Json.Serialization.JsonIgnore] [Newtonsoft.Json.JsonIgnore]
This doesn't seem to work if your controller argument is a contract class that contains a [JsonIgnore]
property.
Hope this can help someone, but when using FromQuery there is no serialization happening as they are simply key/values, so to ignore fields when using FromQuery, decorate your property with the [BindNever] attribute.
Use the [DataContract] for the model and use [DataMember] for the properties which you want to show in Swagger. Any property which isn't marked as [DataMember] doesn't show up in your swagger definition. Let me know if this works or not.
This solution worked for me, thanks a lot
also, to add a greater solution put [IgnoreDataMember] to ignore some attributes or properties you want to ignore
Hope this can help someone, but when using FromQuery there is no serialization happening as they are simply key/values, so to ignore fields when using FromQuery, decorate your property with the [BindNever] attribute.
@breaker05 - Thanks, your solution was exactly what I needed for my project!
If you want to use the [SwaggerIgnore]
attribute (Credits to @vickyrathee) with NSwag:
Create a attribute
SwaggerIgnoreAttribute.cs
using System;
namespace TestApi.Attributes
{
public class SwaggerIgnoreAttribute : Attribute
{
}
}
Create a schema processor
SwaggerSkipPropertySchemaProcessor.cs
using NJsonSchema.Generation;
using TestApi.Attributes;
using System;
using System.Linq;
using System.Reflection;
namespace TestApi.SchemaProcessors
{
public class SwaggerSkipPropertySchemaProcessor : ISchemaProcessor
{
public void Process(SchemaProcessorContext context)
{
if (context.Schema?.Properties == null)
{
return;
}
var skipProperties = context.Type.GetProperties().Where(t => t.GetCustomAttribute<SwaggerIgnoreAttribute>() != null);
foreach (var skipProperty in skipProperties)
{
var propertyToSkip = context.Schema.Properties.Keys.SingleOrDefault(x => string.Equals(x, skipProperty.Name, StringComparison.OrdinalIgnoreCase));
if (propertyToSkip != null)
{
context.Schema.Properties.Remove(propertyToSkip);
}
}
}
}
}
Add to Startup.cs
Startup.cs
services.AddOpenApiDocument(configure =>
{
configure.SchemaProcessors.Add(new SwaggerSkipPropertySchemaProcessor());
});
Use in your class
public class User
{
[SwaggerIgnore]
public long user_id { get; set; }
}
i find finall solution :
it 's work for me
Hope this can help someone, but when using FromQuery there is no serialization happening as they are simply key/values, so to ignore fields when using FromQuery, decorate your property with the [BindNever] attribute.
It's working. Thank you. I've never heard of this attribute.
Hope this can help someone, but when using FromQuery there is no serialization happening as they are simply key/values, so to ignore fields when using FromQuery, decorate your property with the [BindNever] attribute.
It's working for my case using FromQuery. Thank you!
If you want to use the
[SwaggerIgnore]
attribute (Credits to @vickyRathee) with NSwag:Create a attribute
SwaggerIgnoreAttribute.cs
using System; namespace TestApi.Attributes { public class SwaggerIgnoreAttribute : Attribute { } }
Create a schema processor
SwaggerSkipPropertySchemaProcessor.cs
using NJsonSchema.Generation; using TestApi.Attributes; using System; using System.Linq; using System.Reflection; namespace TestApi.SchemaProcessors { public class SwaggerSkipPropertySchemaProcessor : ISchemaProcessor { public void Process(SchemaProcessorContext context) { if (context.Schema?.Properties == null) { return; } var skipProperties = context.Type.GetProperties().Where(t => t.GetCustomAttribute<SwaggerIgnoreAttribute>() != null); foreach (var skipProperty in skipProperties) { var propertyToSkip = context.Schema.Properties.Keys.SingleOrDefault(x => string.Equals(x, skipProperty.Name, StringComparison.OrdinalIgnoreCase)); if (propertyToSkip != null) { context.Schema.Properties.Remove(propertyToSkip); } } } } }
Add to Startup.cs
Startup.cs
services.AddOpenApiDocument(configure => { configure.SchemaProcessors.Add(new SwaggerSkipPropertySchemaProcessor()); });
Use in your class
public class User { [SwaggerIgnore] public long user_id { get; set; } }
For some reason this works with base classes but if you have a child class that also has [SwaggerIgnore] then it wont actually be ignored.
using NJsonSchema.Generation;
using System;
using System.Linq;
using System.Reflection;
namespace Business.Features.Swagger
{
public class SwaggerSkipPropertySchemaProcessor : ISchemaProcessor
{
public void Process(SchemaProcessorContext context)
{
if (context.Schema?.Properties == null)
{
return;
}
var skipProperties = context.ContextualType.Type.GetProperties()
.Where(_ => _.GetCustomAttribute<SwaggerIgnoreAttribute>() != null);
foreach (var skipProperty in skipProperties)
{
var propertyToSkip = context.Schema.ActualProperties.Keys.SingleOrDefault(
_ => string.Equals(_, skipProperty.Name, StringComparison.OrdinalIgnoreCase));
if (propertyToSkip == null)
continue;
if (context.Schema.Properties.ContainsKey(propertyToSkip))
context.Schema.Properties.Remove(propertyToSkip);
else
{
foreach (var schema in context.Schema.AllOf)
{
if(schema.Properties.ContainsKey(propertyToSkip))
schema.Properties.Remove(propertyToSkip);
}
}
}
}
}
}
As an update to my last comment, I figured out how to fix it using this updated version of the code. Not really sure why it is this way, but if your class is a child class it may have multiple JsonSchema
's in the AllOf
variable, but no properties in the Properties
variable. Or maybe it defaults to showing the properties of the parent class, not really sure. But regardless, I found that I can check if Properties
contains the property to skip, then check if AllOf
contains the property to skip and removing it from either seems to accomplish the same thing.
The other change I made is to use ActualProperties
to search for the property to skip, because this always contains all the properties including the parent. ActualProperties
is readonly though, so you can't remove from it.
And the final change is that I used ContextualType.Type
instead of Type
because it said that Type
is obsolete now. It didn't seem to make any difference but w/e
If someone understands this better than me please explain because I don't really understand why it is this way. It's also possible that it's a slight bug
Only the schema filter answer is correct. JsonIgnore
or IgnoreDataMember
are terrible ideas if you care about the property serializing properly. Wish the SwaggerIgnore
attribute was part of the nuget package.
The above solutions didn't work for me, because I'm using a single class to collect all parameters. There are currently general issues collecting all parameters in a single class (https://github.com/dotnet/AspNetCore.Docs/issues/29295). Options to hide are [FromServices]
, ISchemaFilter
, IOperationFilter
, and from the Annotation Extension library [SwaggerSchema(ReadOnly = true)]
. None of them work in all scenarios, but some workarounds are possible. See my post: (https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/2652).
It is not understanding why there is no out of the box support for a swagger ignore attribute. [SwaggerSchema(ReadOnly = true)]
needs to be fixed to work for all scenarios.
Hi, schema.Properties is empty, it's count is 0, why ??? Swashbuckle.AspNetCore 6.5.0
So... Did anyone managed to achieve this? :(
You my create a new
[SwaggerIgnore]
attribute to use that anywhere in your class. Something similarJsonIgnore
, but for Swagger UICreate a attribute
SwaggerIgnoreAttribute.cs
using System; namespace TestApi.Attributes { public class SwaggerIgnoreAttribute : Attribute { } }
Create a filter
SwaggerSkipPropertyFilter.cs
using Microsoft.OpenApi.Models; using TestApi.Attributes; using Swashbuckle.AspNetCore.SwaggerGen; using System.Reflection; namespace TestApi.Filters { public class SwaggerSkipPropertyFilter : ISchemaFilter { public void Apply(OpenApiSchema schema, SchemaFilterContext context) { if (schema?.Properties == null) { return; } var skipProperties = context.Type.GetProperties().Where(t => t.GetCustomAttribute<SwaggerIgnoreAttribute>() != null); foreach (var skipProperty in skipProperties) { var propertyToSkip = schema.Properties.Keys.SingleOrDefault(x => string.Equals(x, skipProperty.Name, StringComparison.OrdinalIgnoreCase)); if (propertyToSkip != null) { schema.Properties.Remove(propertyToSkip); } } } } }
Add to Startup.cs
Startup.cs
services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "Test API", Version = "v1" }); c.SchemaFilter<SwaggerSkipPropertyFilter >(); });
Use in your class
public class User { [SwaggerIgnore] public long user_id { get; set; } }
didnt work :(
ISchemaProcessor
cannot found ISchemaProcessor
So... Did anyone managed to achieve this? :(
same bro
I wanted to do it like this:
public class User { [BindNever] [System.Text.Json.Serialization.JsonIgnore] [Newtonsoft.Json.JsonProperty("user_id ")] public long user_id { get; to define; } }
Try this:
using System.Reflection;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace TestApi.Filters
{
public class IgnoreMeDocumentFilter : IDocumentFilter
{
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
foreach (var schema in swaggerDoc.Components.Schemas)
{
var schemaType = context.ApiDescriptions
.SelectMany(desc => desc.ParameterDescriptions)
.Where(param => param.Type is not null && param.Type.Name == schema.Key)
.Select(param => param.Type)
.FirstOrDefault();
if (schemaType == null)
continue;
var propsToRemove = schemaType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(prop => prop.GetCustomAttribute<IgnoreMeAttribute>() != null)
.Select(prop => prop.Name.ToCamelCase())
.ToList();
foreach (var property in propsToRemove.Where(property => schema.Value.Properties.ContainsKey(property)))
{
schema.Value.Properties.Remove(property);
}
}
}
}
}
Define an empty marker attribute:
[AttributeUsage(AttributeTargets.Property)]
public class IgnoreMeAttribute : Attribute;
Regiter in Program.cs:
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Test API", Version = "v1" });
c.DocumentFilter<IgnoreMeDocumentFilter>();
});
String extension:
public static class StringExtensions
{
public static string ToCamelCase(this string input)
{
if (string.IsNullOrEmpty(input) || char.IsLower(input[0]))
{
return input;
}
var chars = input.ToCharArray();
chars[0] = char.ToLowerInvariant(input[0]);
return new string(chars);
}
}
Use like this:
public record SignIn(
string Username, string Password,
[property:BindNever]
[property: JsonIgnore]
[property: IgnoreMe]
MyHiddenType MyHiddenProp)
: IRequest<MyResponse?>;
[HttpPost("sign-in")]
[Produces("application/json")]
public async Task<IActionResult> Login(SignIn query,
CancellationToken cancellationToken)
{
return Ok(await sender.Send(query, cancellationToken));
}
I have a property that I want to serialize but dont want it visible in Swagger.
Example. public long Id { get; set; }
Things I tried
Any help?
Thanks.