-
Notifications
You must be signed in to change notification settings - Fork 6k
swagger-codegen (c#) issue (or misuse ?) for file upload in a POST Web API operation #2175
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
Comments
I would suggest you to try 2 things:
|
Thank you for your prompt answer. |
The I have a branch which may solve your issue 1255-modify-model-names. This will allow you to add a prefix or suffix to the generated model names, which would help if the |
I'm not sure to fully understand. Do you mean I should modify my Web API Swagger controller code ? Here is the current Web API controller code with its Upload() operation:
Do you suggest I should add a Type argument in the [SwaggerResponse(...)] attribute of the operation's method in my File Web API controller ? For example:
or
Anyway in the meantime I will try these two workarounds. Thank you for your help. |
I just tried to add the type argument in the [SwaggerResponse(...)] attribute of the operation's method:
And I regenerated the client. Nevertheless, the generated client's code still remains the same (refering Object type):
And calling it still raises an exception:
I suppose I did not understand your workaround advice. |
Sorry I was wrong saying the issue remained the same with the latest swagger-codegen master... I didn't correctly regenerated my client with the latest master... (actually, my target/swagger-codegen-cli.jar file was not recompiled !) I've just correctly recompiled it from the latest master and then tried to regenerate my c-sharp client: I now notice the following kind of error messages when generating my client (only on Api with POST operations):
I noticed the .mustache template files have been updated and enhanced but they always contain ambiguous references to Object type. Would they require complementary updates fully specifying the complete namespace IO.Swagger.Model.Object instead of Object in some places ? |
@BugRaptor yeah that's the bug #2064 that I linked to. When I've had the issue, I did just fully qualify the generated Object type manually, then later changed my swagger definition to avoid the issue. Almost all of my Web API routes have |
Ok, Jim. Thank you. But like I just said this morning, with the latest Master, I now cannot even compile my generated client. I get the error CS0104: 'Object' is an ambiguous reference between 'object' and 'IO.Swagger.Model.Object'. I tried to modify the api.mustache and ApiClient.mustache Template files by replacing each Object reference with IO.Swagger.Model.Object. The number of found compiler errors decreased but it still remains Object references in the generated Client Api source code and I don't find any other Object reference to be changed in the mustache c-sharp Template files... |
@BugRaptor As a workaround, can you rename the model "Object" to something else (e.g. DataObject) in the spec? |
@BugRaptor sorry I wasn't clear. What @wing328 suggested is ultimately the fix. When I said "I did just fully qualify the generated Object type manually", I meant in the generated source, I had to edit the .cs files manually to the fully qualified name for If I remember correctly, I used a type alias in all of my files to make the change quickly:
|
Ok. If I understand well, each of my controller Api operation methods must have SwaggerResponse attributes that all must include a not empty response type parameter. So, I defined a DefaultResponse class used for each response previously declared without any response type. All my SwaggerResponse attributes now have this form:
`
This way, my Swagger definition file does NOT contain any 'Object' references that may appear ambiguous when compiling the client. Am I right this way ? |
@BugRaptor It's similar to how I've resolved the issue. This actually affected us while generating the C# client today. Someone on my team messaged me, asking why operations were now returning 'void' rather than 'Object'. In our case, I recently went through and made sure all endpoints had swagger documentation and the problem occurred when I documented a couple places with just:
I recommended a similar fix to yours (returning an empty object). This is the right thing to do from an HTTP standards perspective (https://tools.ietf.org/html/rfc7231#section-6.3.1):
For a response that has no body, I think it's technically more correct to return a status 204 No Content as highlighted above. I'm doing that almost everywhere in my current project but I haven't yet tracked down where others are returning a status 200 with no body. |
@BugRaptor I've made some improvement via #2317. Would you please pull the latest master and give it another try? cc @jimschubert |
@wing328 I've just pulled the latest master and tried to generate my client. I got the following exception:
I attach here after my Swagger doc file: |
Just some news about my issue and long investigations I've recently made on it with my coleagues:
After long investigations I didn't find the root cause of this issue. I especially took care not to close the stream transmitted as parameter before the async call returns. Note that the files I have to upload may be big files, so I want to publish them using a stream and not a static byte array parameter and i need asynchronous client methods to launch the Swagger web api file publishing operation... Any fresh idea to investigate about this issue ? |
Actually, it seams the issue is on RestSharp. The version 105.1.0 seems not to support streaming. I didn't check if the latest RestSharp master does support it, I'll check it on monday.. (There is a pull request from august 2015 seeming to adress this issue but it was not merged becaues of no unit tests,.. ) |
Ok, The "The Request was aborted" exception issue, raised when trying to upload a file as a stream via the C# asynchronous method of the swagger-codegen generated client is definitively located in Restsharp. I was using the recommended version 105.1.0 but the latest release, tagged 105.2.3, does not solve the issue. (The context-length of the http request is set to zero by the client (on asynchronous method) thus the http server aborts the request when the timeout is elapsed...) We finally decided to use the synchronous client method when possible in our application. (The synchronous client method fully reads the stream to a byte array before handling it). For the other contexts where we need the asynchronous client uploading method, we will update our swagger-codegen mustache template files to change the generated asynchronous client code, in order to redirect it to the synchronous byte array handling code. |
restsharp/RestSharp#769 has been merged into the master of RestSharp but I've not seen a new release yet. Once the new release is available, we should give that a try. Would the workaround to use version 105.1.0 be acceptable in your use case? |
Oh ! We didn't even notice this recent merge fixing the content length of the file parameter ! Our mustache workaround for v 105.1.0 is not terminated yet. But I think It would be better to use the next RestSharp nuget package 105.2.4 when released. In the mean time we'll check with a local alpha version issued from the latest master. If it works, we will cancel our workaround developpement and wait for the next release. Is the other bug you mentioned fixed ? (Those that required to stay with version 105.1.0). Thank you. |
That's the only bug that I'm aware of preventing us upgrading to the latest version of RestSharp. |
Ok, we just tried to generate a RestSharp v 150.2.4-alpha prerelease nuget package from the latest master. It now works fine ! Only one Swagger-Codegen client generator update was required in the ApiClient.mustache file (line 106 in the PrepareRequest) to pass a new long parameter to the AddFile method:
The client's async method uploading a file as Stream now finally succeeds without raising the "The request was aborted" exception, and the file content is correctly transmitted to the Web API controller on the server as a Stream. We look forward the RestSharp Version 150.2.4 official release.. Thanks for your help. |
Thanks for the confirmation. We'll keep this issue open before the official RestSharp 150.2.4 release. |
Is there a benefit to setting param.Value.ContentLength versus replacing the AddFile call with |
The swagger-generated code contains a call to a four-argument version of AddFile
This compiles OK using RestSharp 105. However, if I try to build using RestSharp 106, compilation fails because RestSharp 106 does not contain a four-argument AddFile method. I'm not really happy to hand-edit the generated code. Are there plans to make the generated code compatible with RestSharp 106? |
I have a developed a Swagger-Api with a "File" Controller exposing a POST "Upload" operation.
If I upload a file from the Swagger UI, it is correctly uploaded by the "File" Controller.
I then have generated a C# API client class with swagger-codegen. (v2.1.5)
The generated FileApi client class exposes a
public async System.Threading.Tasks.Task<ApiResponse<Object>> FileUploadAsyncWithHttpInfo(Stream file)
method.When I call the
FileApi.FileUploadAsyncWithHttpInfo(stream)
method of the generated Api class, I get an System.AggregateException: "One or more errors occured".The unique inner exception is a IO.Swagger.Client.ApiException: "Error calling FileUpload: The request was aborted."
The stream is a MemoryStream copied from an open FileStream.
I get with the debugger in the FileApi class to see what happens:
Here is the final lines of the
When calling the CallApiAsync method, the parameters values are the following:
After calling the CallApiAsync method, the returned response.StatusCode is 0, its response.Status is Aborted and its response.ErrorMessage is "The request was aborted."
Thus, an ApiException is thrown.
If I get into the CallApiAsync() method, the code is:
The request is prepared and the the RestClient.ExecuteTaskAsync(request) method is called.
The returned response has its StatusCode set to 0, its response.Status is Aborted and its response.ErrorMessage is "The request was aborted."
Do I do something wrong ?
Is there an issue in the swagger-code generated client FileApi class ?
The text was updated successfully, but these errors were encountered: