-
-
Notifications
You must be signed in to change notification settings - Fork 538
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
Missing schema properties in models from interfaces #909
Comments
Not sure if this feature is actually implemented by NJsonSchema... we use Newtonsoft.Json's ContractResolver to enumerate properties - I'd expect that interfaces are also supported by the resolver... but we need to verify this in http://njsonschema.org with a unit test |
This seems to be a Problem with NJsonSchema. Getter and Setter methods are abstract in an Interface and these are not generated by default (see https://github.com/RSuter/NJsonSchema/blob/f7224a3ee33333b3cd439df536f80c5d551dcb21/src/NJsonSchema/Generation/JsonSchemaGenerator.cs#L598 ). Everything works fine if I just set |
NJsonSchema uses the Newtonsoft.Json contract resolver to enumerate properties and do "reflection" over DTOs: This is done to ensure that the schema and the serialized/deserialized data match... The option |
Should I create a corresponding issue in NJsonSchema? I could probably help with writing the UnitTest and potential fix... |
I’ll move this issue over to NJS, but it would be great if you create a (WIP) PR with some tests there... |
Moved to NJS - please create a PR with tests (& maybe a fix) so we can discuss further... |
I added a PR with one test to show the Problem. Also included a potential fix, but i am unsure if this might have any side effects. |
@RSuter : Could you have a look at this fix? Is this the way to go? |
* Add test #929 * Fix property type resolution for any schemas in definitions, RicoSuter/NSwag#2028 * Test and potential Fix for Interfaces. (#909) (#921) * Add legacy support, #921 * v9.13.25
I still have a problem with this. The Properties are now generated, but in an abstract class an can therefore not be deserialized. Am I doing something wrong or is this behavior correct? In my API I have a Interface as a return type. The gerenated TypeScript Class contains all the Properties, but Everthing else seems to be there (e.g. the correct Can I specify somehow, that I want non abstract classes to be genereated for interfaces? |
Theres an option to turn of x-abstract generation |
Could you point me to that option? I can just see the assignment of |
Ah, maybe i was mistaken and there is no such option. Would this solve the problem? I think just allowing abstract class instances would then break on the server as they cannot be deserialized... have you also had a look at the inheritance handling in tandem with abstract classes/interfaces? |
Can you create a pr with your tests for discussions? |
Hmm, yes, I had a quick look at inheritance handling. I currently only use interfaces in return types of my API and have therefore no issue on the server side :-). But I do not use any inheritance (at least I don't want it to be exposed in my schema). How is NJsonSchema involved on the server side? Could it be a solution to generate interfaces and (optionally) an implementation of it to be used? Because just an abstract class (or an interface for that matter) cannot be used at all on the client side. |
NJS is only used for serializing inheritance otherwise its mainly used for generating schemas... Can you provide a comprehensive sample for what you want to achieve? |
Lets assume I have a Controller like this: [RoutePrefix("users")]
public class UserController : ApiController
{
[HttpGet]
[Route("")]
public async Task<IUser> GetCurrentUser()
{
return await GetCurrentUserAsync();
}
} With the public interface IUser
{
string Lastname { get; set; }
string Firstname { get; set; }
} Of course there is an implementation of this interface on the server somewhere, but I do not want to expose it and in my case the API-Layer does not even know about it. I now want to be able to generate TypeScript-Clients that can call this API and handle the Response. Even if I had a Controller like this [RoutePrefix("users")]
public class UserController : ApiController
{
[HttpPost]
[Route("")]
public async Task UpdateUser(IUser user)
{
...
}
} I think clients should be gernerated with concrete DTOs (not abstract ones). How this is deserialized into something meaningful on the server is the servers problem. |
I agree. Need to think about what this was actually trying to solve. But i think x-abstract should only be generated in an inheritance tree (ie when there’s a discriminator etc) - otherwise omitted |
Is the inheritance tree opt-in? Is it only relevant if the |
Yes opt-in with JsonInheritanceConverter, so i’d say we only generate x-abstract if its in an inheritance with JsonInheritanceConverter on the type or any base types |
But i need to check the tests and the code whether that is the correct behavior - not on pc right now |
Sounds good to me, thanks. Tell me if and how I can be of help. |
Should be quite simple to implement/change but i need to ensure that nothing breaks and there are no regressions |
Any news on this? |
Closed by 4643d38 I've added JsonSchemaGeneratorSettings to turn abstract off completely and an JsonSchemaAbstractAttribute to explicitely opt-in or opt-out... is that ok? |
Thanks for the Update (sorry for being late, i did somehow not get an update from github). I am not sure how I should use this. |
Yes, should be available
That's bad, we need to add that |
Could you point me to this option? I cannot see this in NSwagStudio (UI) nor see where I would change that in the nswag.json file. |
The setting has not yet been added to the command (CLI) and UI, but you can already set it in the ASP.NET Core middleware settings... |
Cool, thanks a lot for your work! |
So, when it will be added? |
Just added it. |
When a controller specifies its return type as an interface, NSwag generates an empty model for it. The following is an interface, IFixtureData:
In the swagger.json file, the following is generated:
All of my concrete classes are generated properly, but the interfaces are all like this.
The text was updated successfully, but these errors were encountered: