RicoSuter / NSwag

The Swagger/OpenAPI toolchain for .NET, ASP.NET Core and TypeScript.
http://NSwag.org
MIT License
6.79k stars 1.29k forks source link

NSwag studio code generation unwraps the class properties and puts them in as parameters rather than the object itself. #1464

Open patel-jeel92 opened 6 years ago

patel-jeel92 commented 6 years ago

WebAPI targets .NET Core 2.1

I have an api call which takes in my custom object as a parameter. When I generate the client code using NSwag Studio, it unwraps all the properties of the custom object and puts those as parameters rather than the object itself. As a result my client looks like this:

System.Threading.Tasks.Task AddNewPerson(string name, int age, sting zodiacSign);

instead of

System.Threading.Tasks.Task AddNewPerson(Person person);

smariussorin commented 6 years ago

Same problem, used [FromBody] to fix de issue.

Kordonme commented 6 years ago

[FromBody] won't work with GET. This is still an issue and should be a setting.

Caraballo114 commented 5 years ago

Any update on this? I'm having the same issue as well. I don't want to [FromBody] all my APIs, as it'd make more sense to get the inital issue fixed. I'm guessing this has something to do with the CodeGen.nswag configuration?

RicoSuter commented 5 years ago

Cant this be solved with a custom asp.net core api convention?

rrr3da commented 5 years ago

immo the issue must be solved during json generation step, but I'm not really into openapi specs so maybe this is not standard to achieve. I would be nice from this controller

[HttpGet]
[ProducesResponseType(typeof(Contact), 200]
public IActionResult Get([FromQuery]ContactQuery query) { ... }

(which produces this output json)...

{
  "v1/contacts": {
    "get": {
      ...
      "parameters" : [
        <each ContactQuery field>
      ]
    }
  }
}

...to have a generated client with the ContactQuery model instead of single split parameters

packe100 commented 5 years ago

Hi! I have the same problem: the complex parameters decorated as "[FromQuery]" are translated with a list of primitive type properties.

Are there news about the resolution of this issue?

RicoSuter commented 5 years ago

The problem is that this cannot be described with openapi/swagger

packe100 commented 5 years ago

Hi, thank you for your answer.

That being the case (i.e. no support from openapi), I would say that what I'm trying to do - FromQuery argument automation - is not a common/orthodox practice. Is there probably a better solution?

madhavpatel6 commented 3 years ago

Any progress on this?

DavisZ94 commented 2 years ago

Has someone found a work-around for this? It gets pretty annoying when you have GET endpoint with 20~ search parameters

CedricBaetens commented 2 years ago

Would love a solotion for this problem. Any news?

magicxor commented 1 year ago

Related issues/duplicates: https://github.com/RicoSuter/NSwag/issues/1193 https://github.com/RicoSuter/NSwag/issues/3301 https://github.com/RicoSuter/NSwag/issues/3486

magicxor commented 1 year ago

There is a software swagger-typescript-api that creates more convenient signatures for complex DTOs in GET requests:

image

Maybe we could use it as a reference to implement a similar feature in NSwag

adampaquette commented 1 year ago

The option to generate DTO classes for input/output parameters works but is not used inside the C# client. It still use flattened parameters.

brian-kane521 commented 11 months ago

I was able to solve this using a modified version of the solution here: https://tkit.dev/2020/03/10/complex-get-query-param-objects-in-swashbuckle/

brian-kane521 commented 11 months ago

The link in my previous comment causes correct code generation and the Swagger webpage behaves as expected, however NSwagStudio does not generate the correct code.

eduardheller89 commented 8 months ago

@brian-kane521 can you show us your modified version of the solution?

brian-kane521 commented 8 months ago

@eduardheller89 I ended up reverting my c# back to standard and instead using a custom liquid template for NSwagStudio to generate typescript API calls using classes/objects instead of each individual parameter.

For a controller with a signature like this:

[HttpGet]
public async Task<ActionResult<ResponseType>> GetSomething([FromQuery] RequestType request)
{ // code here }

NSwagStudio will generate the following in the typescript client:

export class getSomethingParametersDto {
    param1: number[];
    param2: boolean;
    // etc
}

getSomethingDto(body: getSomethingParametersDto ): Promise<ResponseType> {

        const content_ = Object.keys(body as any).map((key) => {
            return encodeURIComponent(key) + '=' + encodeURIComponent((body as any)[key]);
        }).join('&')

        let url_ = this.baseUrl + "/api/Something?" + content_;

        let options_: RequestInit = {
            method: "GET",
            headers: {
                "Accept": "text/plain"
            }
        };

        return this.transformOptions(options_).then(transformedOptions_ => {
            return this.http.fetch(url_, transformedOptions_);
        }).then((_response: Response) => {
            return this.transformResult(url_, _response, (_response: Response) => this.processGetSomething(_response));
        });
    }

Essentially, the generated code will translate from an object to individual query parameters. This has no effect on the generated swagger JSON or c# behavior, so while it solved the usability problem I was hoping to solve, it might not be the best approach if you're concerned about 3rd party API consumers etc.

Here's the liquid template I wrote: FetchClient.zip

eduardheller89 commented 8 months ago

@brian-kane521 thanks for the quicks response and solution. But I am afraid I am using third party api consumer, so I need the query parameters as a ref inside parameters groups as schema. Do you still have the IOperationFilter extensions in nswag which produces the code mentioned in the article? I tried but failed to convert it to nswag.

brian-kane521 commented 8 months ago

@eduardheller89 Are you having issues with the code as-is from the article? Looking back at my git history, I only made minor modifications to conform with .NET 6/C# 10. I can post the code here but it is functionally the same, so if you're having other issues it probably will not resolve them.