Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to get rid of all abstract classes, generated in the Models section? #2998

Open
MagicMaxxx opened this issue Aug 12, 2020 · 7 comments
Open

Comments

@MagicMaxxx
Copy link

MagicMaxxx commented Aug 12, 2020

Hello!

ASP.NET Core 3.1, WebAPI.

I have just about 8 methods (like Login, Register... Ping.. and so on), but services.AddSwaggerDocument(..) generates about 50+ classes in the swagger document (https://localhost:44398/swagger/index.html), below in the Models section. These classes came from the whole solution and also there are a lot of abstract classes over here. All of these classes are just public classes. Also, I do not use attributes (like [DataMember] or [Json...]) to control serialization...

Question is - how to control, what class should be there in that section? I planned to have just method parameters there... I tried to use services.AddSwaggerDocument(opt => {../* here */..}) construction in the Startup.cs but had no luck...

Thanks!

@jeremyVignelles
Copy link
Collaborator

You need to be a bit more precise. Your localhost help won't help (we can't access your localhost...).

If many classes gets included, that usually means that you set a parameter or a return type to a type that was not meant to be serialized.

NSwag isn't supposed to generate 50 classes for simple cases like yours. If those advices didn't help, please share a minimal code that reproduces your issue.

@MagicMaxxx
Copy link
Author

You need to be a bit more precise. Your localhost help won't help (we can't access your localhost...).

If many classes gets included, that usually means that you set a parameter or a return type to a type that was not meant to be serialized.

NSwag isn't supposed to generate 50 classes for simple cases like yours. If those advices didn't help, please share a minimal code that reproduces your issue.

Well, I've updated my question above, and right after that, I've got your response - thanks for the answer!

I understand that you can't access my localhost link - it just a sample of URL where I found Models section :)

Here is a piece of code I tried to use in the Startup.cs:

        services.AddSwaggerDocument(opt =>
        {
            DefaultContractResolver resolver = opt.ActualContractResolver as DefaultContractResolver;
            //resolver.SerializeCompilerGeneratedMembers = false;
            //JsonSerializerSettings settings = opt.ActualSerializerSettings;

            //opt.RequireParametersWithoutDefault = true;
            opt.GenerateAbstractSchemas = false;
            opt.GenerateAbstractProperties = false;
            //opt.GenerateExamples = false;
            //opt.SchemaGenerator.Settings.

            opt.AddOperationFilter(ctx =>
            {
                return true;
            });
     }

but here I can't figure out how to filter all that Models that are in the Models list on the Swagger page... The goal of my question is to get rid of all abstract classes and classes that are not parameters/results of WebAPI methods...

@MagicMaxxx
Copy link
Author

MagicMaxxx commented Aug 12, 2020

Annotation 2020-08-12 184101
The class marked with yellow is an abstract class...

@jeremyVignelles
Copy link
Collaborator

Are these the base classes of your models ? In your APIs, you should use DTO objects (objects that are made specifically for the json serialization/deserialization), and not your internal objects, otherwise NSwag will try to serialize the complete object hierarchy.

@MagicMaxxx
Copy link
Author

MagicMaxxx commented Aug 12, 2020

I don't think that this is a good idea to show (at least) abstract classes... It would be good to have some method to control Models like you control Operations:
services.AddSwaggerDocument(opt => { opt.AddOperationFilter(ctx => { return false; }); });
Here, if you return FALSE - there will be no Operations (methods in WebAPI) at all...

@jeremyVignelles
Copy link
Collaborator

You could edit the generated items, but I think there's value in generating every abstract class in the hierarchy.

Say you have the Apple and Orange classes, based on the Fruit abstract class.
How would you declare your Eat(Fruit) method without that abstract class? Would you duplicate the Weight property on both Apple and Orange ?

You have two solutions for your specific use case. Either you use a DocumentProcessor, or you clean up your API by only using serializable DTO objects without a base class, and copy the values in your internal classes manually.

@RicoSuter
Copy link
Owner

You can flatten all inheritance chains with FlattenInheritanceHierarchy config:

https://apimundo.com/organizations/nuget-org/nuget-feeds/public/packages/NJsonSchema/versions/latest?tab=types&type=NJsonSchema.Generation.JsonSchemaGeneratorSettings

or you add the [JsonSchemaFlatten] attribute to the classes which should not have base classes:

https://github.com/RicoSuter/NJsonSchema/blob/master/src/NJsonSchema/Annotations/JsonSchemaFlattenAttribute.cs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants