Skip to content

[REQ] [csharp] option to use asynchronous callbacks or generate it by default. #7265

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

Open
jonaslagoni opened this issue Aug 20, 2020 · 4 comments

Comments

@jonaslagoni
Copy link

Is your feature request related to a problem? Please describe.

This is a dublicate issue from swagger-api/swagger-codegen#10424

I want to have the option of asynchronously call the api with the csharp generator. I am unable to use the generator csharp-netcore which has this feature.

Describe the solution you'd like

With the following document

swagger: '2.0'
tags:
- name: Server
  description: Operations available to retrieve information about a server
paths:
  /servers/{server_id}:
    get:
      tags:
        - Server
      summary: Get basic server information
      operationId: getServer
      description: |
        This returns basic information about a specific server
      parameters:
        - name: server_id
          in: path
          description: The server id to retrieve the basic information about
          type: integer
          required: true

This is what I changed in the old generated code and what could be generated alongside/in replacement.

Add a method called CallApiAsync to the generated ApiClient

        public void CallApiAsync(String path, RestSharp.Method method, Dictionary<String, String> queryParams, String postBody,
            Dictionary<String, String> headerParams, Dictionary<String, String> formParams,
            Dictionary<String, FileParameter> fileParams, String[] authSettings, Action<IRestResponse> callback)
        {

            var request = new RestRequest(path, method);

            UpdateParamsForAuth(queryParams, headerParams, authSettings);

            // add default header, if any
            foreach (var defaultHeader in _defaultHeaderMap)
                request.AddHeader(defaultHeader.Key, defaultHeader.Value);

            // add header parameter, if any
            foreach (var param in headerParams)
                request.AddHeader(param.Key, param.Value);

            // add query parameter, if any
            foreach (var param in queryParams)
                request.AddParameter(param.Key, param.Value, ParameterType.GetOrPost);

            // add form parameter, if any
            foreach (var param in formParams)
                request.AddParameter(param.Key, param.Value, ParameterType.GetOrPost);

            // add file parameter, if any
            foreach (var param in fileParams)
                request.AddFile(param.Value.Name, param.Value.Writer, param.Value.FileName, param.Value.ContentType);

            if (postBody != null) // http body (model) parameter
                request.AddParameter("application/json", postBody, ParameterType.RequestBody);
            RestClient.ExecuteAsync(request, callback);

        }

Change the generated client interface form from

Server GetServer (int? serverId);

to

void GetServer (int? serverId, Action<ApiException, Server> callback);

Change the generated client methods from:

        public Server GetServer (int? serverId)
        {
            
            // verify the required parameter 'serverId' is set
            if (serverId == null) throw new ApiException(400, "Missing required parameter 'serverId' when calling GetServer");
            
    
            var path = "/servers/{server_id}";
            path = path.Replace("{format}", "json");
            path = path.Replace("{" + "server_id" + "}", ApiClient.ParameterToString(serverId));
    
            var queryParams = new Dictionary<String, String>();
            var headerParams = new Dictionary<String, String>();
            var formParams = new Dictionary<String, String>();
            var fileParams = new Dictionary<String, FileParameter>();
            String postBody = null;
    
            // make the HTTP request
            IRestResponse response = (IRestResponse) ApiClient.CallApi(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings);
    
            if (((int)response.StatusCode) >= 400)
                throw new ApiException ((int)response.StatusCode, "Error calling GetServer: " + response.Content, response.Content);
            else if (((int)response.StatusCode) == 0)
                throw new ApiException ((int)response.StatusCode, "Error calling GetServer: " + response.ErrorMessage, response.ErrorMessage);
    
            return (Server) ApiClient.Deserialize(response.Content, typeof(Server), response.Headers);
        }

to

        public void GetServer (int? serverId, Action<ApiException, Server> callback)
        {
            
            // verify the required parameter 'serverId' is set
            if (serverId == null) throw new ApiException(400, "Missing required parameter 'serverId' when calling GetServer");
            
    
            var path = "/servers/{server_id}";
            path = path.Replace("{format}", "json");
            path = path.Replace("{" + "server_id" + "}", ApiClient.ParameterToString(serverId));
    
            var queryParams = new Dictionary<String, String>();
            var headerParams = new Dictionary<String, String>();
            var formParams = new Dictionary<String, String>();
            var fileParams = new Dictionary<String, FileParameter>();
            String postBody = null;

            // make the HTTP request
            ApiClient.CallApiAsync(path, Method.GET, queryParams, postBody, headerParams, formParams, fileParams, authSettings, (response) =>
            {
                ApiException exception = null;
                if (((int)response.StatusCode) >= 400)
                    exception = new ApiException((int)response.StatusCode, "Error calling GetServer: " + response.Content, response.Content);
                else if (((int)response.StatusCode) == 0)
                    exception = new ApiException((int)response.StatusCode, "Error calling GetServer: " + response.ErrorMessage, response.ErrorMessage);

                callback(exception, (Server)ApiClient.Deserialize(response.Content, typeof(Server), response.Headers));
            });
        }

Describe alternatives you've considered

Tried to use the charp-netcore generator which has a version of this feature but it has to be compatible with .NET Framework 4.5. Tried to use the original swagger-codegen library which also does not have this feature.

@auto-labeler
Copy link

auto-labeler bot commented Aug 20, 2020

👍 Thanks for opening this issue!
🏷 I have applied any labels matching special text in your issue.

The team will review the labels and make any necessary changes.

@jonaslagoni
Copy link
Author

Already implemented with Tasks, no idea why I didnt notice that.

@jonaslagoni
Copy link
Author

Gonna reopen, I could really use the Action callback variant instead of using Tasks. I am restricted in using all features of System.Threading directly in my code.

@jonaslagoni jonaslagoni reopened this Aug 23, 2020
@devhl-labs
Copy link
Contributor

You can make this happen now if you use the -t template option. Just save the mustache template to your disk and specify -t pathToDirectory

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

2 participants