Swashbuckle.AspNetCore.Filters icon indicating copy to clipboard operation
Swashbuckle.AspNetCore.Filters copied to clipboard

Support hiding empty fields

Open effyteva opened this issue 6 years ago • 13 comments

Hi,

When we create a example with only some properties, the SwaggerUI still generates all the fields as null. Perhaps a new feature could be added for hiding those fields?

Thanks, Effy

image

effyteva avatar Dec 20 '18 08:12 effyteva

Hi Effy,

This is by design - the ExamplesOperationFilter will use whatever JSON serializer settings your app is configured with. This feature was introduced recently by request - it fixed #72 .

If you roll back to 4.5.1 it will revert to the previous behaviour, which is to ignore nulls.

Or you could change the behaviour of your app, by setting the global serializer settings (recommended):

public void ConfigureServices(IServiceCollection services)
{
     services.AddMvc()
             .AddJsonOptions(options => {
                options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
     });
}

Or, you could possibly override IContractResolver and pass that into the SwaggerRequestExample or SwaggerResponseExample attribute.

mattfrear avatar Dec 21 '18 07:12 mattfrear

Thank you @mattfrear However, I don't think the recommended solution is feasible for existing applications. Our API is already in use. By changing this parameter globally we might break existing clients, as all null values will now be removed from the response. Any change you could upload an example of the IContractResolver solution?

Alternatively, I believe it would make much sense to allow modifying the SerializerSettings for both Request/Response (Requests should render nulls, yet Responses should render nulls on our use case).

Effy

effyteva avatar Feb 11 '19 15:02 effyteva

Hi Effy

Any change you could upload an example of the IContractResolver solution?

Unfortunately IContractResolver wouldn't work, my suggestion was incorrect. Sorry about that.

Alternatively, I believe it would make much sense to allow modifying the SerializerSettings for both Request/Response (Requests should render nulls, yet Responses should render nulls on our use case).

Can you clarify what makes sense for your use case? Requests should render nulls - yes or no? Responses should render nulls - yes or no?

I guess I could extend the SwaggerRequestExampleAttribute and SwaggerResponseExampleAttribute and add a renderNulls bool to support this, but I don't have a lot of time. And I'd need to add documentation and unit tests etc etc. You are welcome to submit a PR for this.

mattfrear avatar Mar 03 '19 16:03 mattfrear

Thank you for the response @mattfrear

On our use case, requests shouldn't render nulls, as they represent basic sample requests. For instance, when issuing a new invoice using our API, the customer email address field is required, however the phone number is optional, and isn't shown in the example, to keep is shown and simple to understand.

On the responses we don't have a major preference, and we'll probably prefer them to not render nulls as well.

I'll try to get into it and publish the PR you recommended.

Thanks, Effy

effyteva avatar Mar 03 '19 16:03 effyteva

Cool. If you do a PR then please add tests too, and update the ReadMe.

mattfrear avatar Mar 03 '19 16:03 mattfrear

Our API is already in use. By changing this parameter globally we might break existing clients, as all null values will now be removed from the response.

Really? In my experience if the clients are .NET, then model binding treats a null the same as a missing property. This follows Postel's law. https://en.wikipedia.org/wiki/Robustness_principle

I'm don't think I want to add more code (i.e. a renderNulls property to my attributes) for this. I am thinking about dropping support for the custom IContractResolver and JsonConverter types too, as I never use those attributes and I'm not sure if anyone does.

I'm going to close this because I'm not going to implement it.

mattfrear avatar May 30 '19 04:05 mattfrear

I have the following set .AddJsonOptions(o => o.JsonSerializerOptions.IgnoreNullValues = true) and it is still including null values.

@mattfrear Can we get this to work with System.Text.Json?

davidhenley avatar Nov 06 '19 21:11 davidhenley

@davidhenley which version of my library are you using? It used to work...

mattfrear avatar Nov 22 '19 19:11 mattfrear

@mattfrear we just tried @davidhenley solution, and sadly it didn't work as well. We used the latest 5.0.0 rc5 version

effyteva avatar Dec 14 '19 17:12 effyteva

Latest version here, it doesn't work.

Maybe I got this wrong, but isn't this forcing the use of the default NewtonsoftJson properties instead of the properties we configured with JsonOptions from System.Text.Json? This is ignored:

public void ConfigureServices(IServiceCollection services)
{
  services.AddControllers().AddJsonOptions(options =>  {
    options.JsonSerializerOptions.IgnoreNullValues = true;
  });
}

I think this implementation from Swashbuckle.AspNetCore might help.

diegosps avatar Apr 14 '20 20:04 diegosps

@diegosps thanks for the investigation.

Yes, this library has been around a long time, when the only Json serializer in town was the Newtonsoft one.

@davidhenley which version of my library are you using? It used to work...

Yeah, it only works if you're using the Newtonsoft serializer.

I'll see if diego's suggestion works. It might be a lot of work to untangle the Newtonsoft serializer from this project.

mattfrear avatar Apr 15 '20 04:04 mattfrear

I'm going to copy/paste this advisory to any open issues that are for ExamplesOperationFilter.

https://github.com/mattfrear/Swashbuckle.AspNetCore.Filters#do-not-use-this-filter-unless-you-have-to

Swashbuckle.AspNetCore supports adding examples from XML documentation, which might already cover your use case, in which case you can stop using this package and close your issue.

If examples from XML documentation doesn't work for you, then feel free to leave your issue open.

mattfrear avatar Apr 21 '20 10:04 mattfrear

If you're using Newtonsoft's serializer, this works with the current version:

.NET Core 3.1

services
    .AddControllers()
    .AddNewtonsoftJson(opt => opt.SerializerSettings.NullValueHandling = NullValueHandling.Ignore)

.NET Core 2.1 (as described already)

services
    .AddMvc()
    .AddJsonOptions(opt => opt.SerializerSettings.NullValueHandling = NullValueHandling.Ignore)

As discussed above, this doesn't yet work if you're using System.Text.Json. Support for that might be added later.

mattfrear avatar Apr 30 '20 09:04 mattfrear