Issues with Swagger-codegen for C#

2,350 views
Skip to first unread message

Amit Bansal

unread,
Sep 1, 2015, 5:30:44 AM9/1/15
to Swagger
Hi Team,

I am trying to generate client-side code using Swagger-codegen [java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate -i test.json -l csharp -o test/]. I am using the v2/api-docs[json] for codegen. I am facing the following issues:

  1. The RestSharp.dll generated does not have RestClient.addQueryParameters. Looks like its being used when creating a REST Request.This looks like a dependency issue. This was fixed when i manually created a dll from the latest RestSharp library. It will be great if the auto-generated dll is the latest version. Error:

          src\main\csharp\IO\Swagger\Client\ApiClient.cs(66,17): error CS1061:
            'RestSharp.RestRequest' does not contain a definition for
            'AddQueryParameter' and no extension method 'AddQueryParameter'
            accepting a first argument of type 'RestSharp.RestRequest' could be
            found (are you missing a using directive or an assembly reference?)
    src\main\csharp\IO\Swagger\Client\ApiClient.cs(80,40): error CS1061:
            'RestSharp.RestClient' does not contain a definition for
            'ExecuteTaskAsync' and no extension method 'ExecuteTaskAsync' accepting
            a first argument of type 'RestSharp.RestClient' could be found (are you
            missing a using directive or an assembly reference?)
     

  2. Is there a way to add some parameters to the url formed for server call ? Use case: My services returns xml response by default. I can override this by appending "format=json" to the url. SInce Swagger supports Deserialization only for Json response, i need a solution for this. Another alternative can be to plug-in a custom deserializer. Please let me know the feasibility of both the options.

  3. Is there a option to override the default communication protocol - HTTPS? My services are HTTP based, So i need a way to override the basePath "https://<hostName>:<portNumber>" generated in ApiClient.cs, to "http://<hostName>:<portNumber>, ie, use http protocol.

  4. The Client was trying to use IO.Swagger.Model [using IO.Swagger.Model;] which was not needed and didn't exist, if we don’t have any model dependency. Please let me know if this is a bug.

  5. Although C# has char as a primitive data type, char in java gets converted to string in C#. Is this a bug or an expected behavior? Example:
    My java method looks like :
          Interface:
              
    char getChar();
          Impl:
                  @Override
                  @ApiOperation(value = "This is test service - getChar")
          @RequestMapping(value = "/getChar", method = GET)
                 @ResponseBody
          public char getChar() {
    return 'a';
         }
    C#:
               string GetCharUsingGET ();

  6. Is there a bug in the support of 2D arrays? The generated C# should say List<List<int>>, instead it says List<List>, which is a compilation issue.
    My java method looks like :
          Interface:
              
    int[][] getPrimitiveDouble3();
          Impl:
                  @Override
                  @ApiOperation(value = "This is test service - getPrimitiveDouble3")
          @RequestMapping(value = "/getPrimitiveDouble3", method = GET)
                 @ResponseBody
          public int[][] getPrimitiveDouble3() {
    return null;
         }
    C#:
               List<List> GetPrimitiveDouble3UsingGET ();

  7. Is there a way to overwrite the default namespace? Example: from "IO.Swagger.Api" to "MyService.Api" 
Please guide me on the above issues.
Thanks,
Amit Bansal

wing328

unread,
Sep 4, 2015, 2:53:40 AM9/4/15
to Swagger
Hi Amit,

1. It looks like you're not using the latest master, which include RestSharp 105.1.0.0. The issue was resolved before and tracked here: https://github.com/swagger-api/swagger-codegen/pull/775. Would you please pull the latest master (https://github.com/swagger-api/swagger-codegen) and do a 'mvn clean install` before generating the C# API client?

2. Does your server respect the "Accept" in the HTTP request? If yes, you can define "consumes" for the endpoint to include "application/json".

3. The schemes is defined in the Swagger spec. It's entirely your choice to use http or https.

4. Looks more like you're not using the latest version. Issue resolved and tracked here: https://github.com/swagger-api/swagger-codegen/issues/929

I'll stop here for the time being while you try to test again with the latest version.

Best,
William






Amit Bansal於 2015年9月1日星期二 UTC+8下午5時30分44秒寫道:

Amit Bansal

unread,
Sep 7, 2015, 8:02:02 AM9/7/15
to Swagger
Hi William,

Thank you for your response. I started using the latest jars, and i do not see the issues 1 and 4 anymore. 

2.[Resolved] The way my application is written is, if i pass a "query parameter" with format=json [Ex: https://amitbansal-dev.hyd.abc.com:9342/testService/getInt?format=json], it will return the response in json format. So, i wanted to know if i can somehow add a default "query parameter" to all my server calls. For now, i have resolved this by modifying the existing template to add [request.AddQueryParameter("format", "json")] by default in the "PrepareRequest" method generated in ApiClient.js.

3.[Resolved] I understand your point So. i resolved this by overriding the default ApiClient :
=================================================================================
            ApiClient c = new ApiClient("http://amitbansal-dev.hyd.abc.com:9342/");
            TestApi t = new TestApi(c);
=================================================================================

[New Query]
8. As we know that currently, codegen does not support Enums, Please let me know if there is a work-around for this. 

9. Is it feasible to plug-in custom serializer/de-serializer for specific "model objects"/"data types" [Ex: java.util.Date] in Swagger codegen? Please point me to some examples/documentation for the same. 

In addition to 8 and 9, please respond to the queries 5,6,7 as well.

Thanks,
Amit Bansal 

wing328

unread,
Sep 8, 2015, 3:32:36 AM9/8/15
to Swagger
Hi,

Here you go:

5) The method name (operationId) is kind of "fixed". The only thing codegen would do is to convert it into snake_case or camelCase.

6) Please help open an issue in https://github.com/swagger-api/swagger-codegen/issues (Swagger spec 1.2 does not support 2D array. Only Swagger spec 2.0 does)

7) For 7, you need to support a JSON config file via the -c command line argument, e.g.

  java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate \
  -i /var/tmp/road_scholar.yaml \
  -l csharp \
  -o /var/tmp/csharp/test/ \
  -c /var/tmp/csharp.json

Here is an example of /var/tmp/csharp.json:

{

  "packageName": "com.testing"

}

 
For options available in the JSON config, please run "java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar config-help -l csharp"

8) Maybe just use "string" instead

9) What about extending ApiClient to override the methods.

Best,
William

Amit Bansal於 2015年9月7日星期一 UTC+8下午8時02分02秒寫道:

Amit Bansal

unread,
Sep 8, 2015, 8:27:30 AM9/8/15
to Swagger
Hi William,
Thanks for responding. Please look at my comments below:

5) The issue here is the return type is being changed from char to string.
    "public char getChar()" gets mapped to "string GetCharUsingGET ()"

     Ideally the primitive data types should be mapped accordingly. Please let me know if this is a bug.


7) The given solution will work out, thanks !

For 8 and 9, i will try to evaluate your suggestions and few more alternatives like changing the template files, and update.

[New Query]
10) Issues were seen for nested maps as well: Map<String, Map<String, String>> gets converted to Dictionary<String, Map«string,string»> [a model object "Map«string,string».cs" was generated], instead of Dictionary<String, Dictionary<String, String> >

As a result, it gives compilation issue on the generated client code. Sample error:
Generated Code:
        /// <summary>
        /// This is test service 
        /// </summary>
        /// <returns>Dictionary<String, Map«string,string»></returns>            
        Dictionary<String, Map«string,string»> GetComplexMapUsingGET ();
Error:
     src\main\csharp\IO\Swagger\Api\TestApi.cs(132,31): error CS1056: Unexpected
            character '«'
    src\main\csharp\IO\Swagger\Api\TestApi.cs(132,45): error CS1056: Unexpected
            character '»'

11) In the compile.bat generated as part of codegen, there is a segment saying "/doc:bin/IO.Swagger.xml". When i try to execute this using cmd [start compile.bat], it gives the following issue:

    src\main\csharp\IO\Swagger\Api\TestApi.cs(10,22): warning CS1591: Missing XML
            comment for publicly visible type or member 'IO.Swagger.Api.ITestApi'
    src\main\csharp\IO\Swagger\Api\TestApi.cs(82,35): warning CS1570: XML comment on
            'IO.Swagger.Api.ITestApi.GetDatesUsingGET()' has badly formed XML -- 'A
            name contained an invalid character.'
    src\main\csharp\IO\Swagger\Api\TestApi.cs(88,35): warning CS1570: XML comment on
            'IO.Swagger.Api.ITestApi.GetDatesUsingGETAsync()' has badly formed XML
            -- 'A name contained an invalid character.'


    Can you please tell me what is the use of "/doc:bin/IO.Swagger.xm" do? [FYI: the error doesn't come if i remove this part]

Thanks,
Amit

Amit Bansal

unread,
Sep 8, 2015, 11:12:50 AM9/8/15
to Swagger
Hi,
For issue 10,

It looks like the intermediate json generated by Springfox-Swagger is erroneous:

Piece from the intermediate json:

"/service/testService/getInnerMap":{"get":{"tags":["test"],"summary":"This is test service","operationId":"getInnerMapUsingGET","consumes":["application/json"],"produces":["*/*"],"responses":{"200":{"description":"OK","schema":{"type":"object","additionalProperties":{"$ref":"#/definitions/Map«string,string»"}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}}

Here, if you see "#/definitions/Map«string,string»", it should be ideally "#/definitions/Map<string,string>". Hence it gives compilation issue. I think it is a bug, correct me if i am wrong.

Thanks,
Amit

Tony Tam

unread,
Sep 8, 2015, 12:10:23 PM9/8/15
to swagger-sw...@googlegroups.com
Actually that definition key should never exist. A map is described with 'additionalProperties: true' per JSON schema. 

Thus, this reference:

"#/definitions/Map<string,string>"
Is not acceptable in swagger. 
--
You received this message because you are subscribed to the Google Groups "Swagger" group.
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

wing328

unread,
Sep 8, 2015, 11:39:28 PM9/8/15
to Swagger
(for some reasons my email reply below didn't make it to this list, posting it again)

"$ref":"#/definitions/Map«string,string»" is not a correct definition of map. Please refer to https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#model-with-mapdictionary-properties for examples of map/dictionary

For 5), there's no such thing as "char" in swagger date type: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#data-types. String is the closest to char.

For compile.bat, I'll take a look later. A workaround is compile the SDK using an IDE (e.g. Visual Studio. Xamarin). Please also open an issue in the swagger-codegen project page for tracking.

William


tony tam於 2015年9月9日星期三 UTC+8上午12時10分23秒寫道:
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggersocket+unsub...@googlegroups.com.

William Cheng

unread,
Sep 9, 2015, 2:34:27 AM9/9/15
to swagger-sw...@googlegroups.com
"$ref":"#/definitions/Map«string,string»" is not a correct definition of map. Please refer to https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#model-with-mapdictionary-properties for examples of map/dictionary

For 5), there's no such thing as "char" in swagger date type: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#data-types. String is the closest to char.

For compile.bat, I'll take a look later. A workaround is compile the SDK using an IDE (e.g. Visual Studio. Xamarin)

William

--
You received this message because you are subscribed to a topic in the Google Groups "Swagger" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/swagger-swaggersocket/AoNJh01yk_I/unsubscribe.
To unsubscribe from this group and all its topics, send an email to swagger-swaggers...@googlegroups.com.

Amit Bansal

unread,
Sep 9, 2015, 4:12:31 AM9/9/15
to Swagger
Hi,

I understand your point that, "$ref":"#/definitions/Map«string,string»" is not a correct definition of map. However, I generated the spec using Springfox-Swagger. Please let me know if there is an alternative of generating the spec or handling similar error scenarios. I faced the same issue with multi-dimensional array as well [https://github.com/swagger-api/swagger-codegen/issues/1202]
Opened an issue in springfox for this [https://github.com/springfox/springfox/issues/956]

As for 5), i agree that string is the closest match to char, in case char is not supported. Thanks for clarifying this. Just an idea, i think, similar data types should be mapped across languages like char<->char, string<->string etc.

For compile.bat, i will try the workaround and update. Also, created an issue for the same [https://github.com/swagger-api/swagger-codegen/issues/1204]

Thanks,
Amit Bansal
To unsubscribe from this group and all its topics, send an email to swagger-swaggersocket+unsub...@googlegroups.com.

Amit Bansal

unread,
Sep 9, 2015, 11:44:47 AM9/9/15
to Swagger
Hi All,
I am seeing few more issues:

12) Simple Map
Code:
>> @Override
    @ApiOperation(value = "This is test service")
    @RequestMapping(value = "/getMap", method = GET)
    @ResponseBody
    public Map<String, String> getMap(Map<String, String> m);

Generated Spec
>>
"/service/testService/getMap":{"get":{"tags":["test"],"summary":"This is test service","operationId":"getMapUsingGET","consumes":["application/json"],"produces":["*/*"],"parameters":[{"in":"body","name":"m","description":"m","required":false,"schema":{"type":"object","additionalProperties":{"type":"string"}}}],"responses":{"200":{"description":"OK","schema":{"type":"object","additionalProperties":{"type":"string"}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}}

If you see, the generated spec is in accordance with https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#model-with-mapdictionary-properties. However, the C# generated code looks like:
>> public Dictionary<String, string> GetMapUsingGET (Object m)

a) The input parameter should be Dictionary<string, string>, instead it is getting converted to an object. Please let me know if this a bug. b) [Not a Major issue, just a doubt] Also, the return type is generated as "Dictionary<String, string>". Why is there an inconsistency in this("String" and "string")? Is this expected

13) Codegen for Model Objects:

I have a simple Model Object, as follows:
>> public class Bundle
{
private Integer myBundleId;
private Integer myBookId;
private Integer myParentBookId;
private String myName;
private String myAbbrev;

public Integer getBundleId()
{
return myBundleId;
}
.......

The model object generated by codegen looks like:
>>


This gives a compilation issue as visible from the screenshot. Please let me know what can i do here?

Thanks,
Amit

14) @RequestParam for Maps [Not a major issue]
Code:
>> @Override
@ApiOperation(value = "This is test service")
@RequestMapping(value = "/getMap", method = GET)
@ResponseBody
public Map<String, String> getMap(@RequestParam Map<String, String> m) ;

Generated Spec:
>>

,"/service/testService/getMap":{"get":{"tags":["test"],"summary":"This is test service","operationId":"getMapUsingGET","consumes":["application/json"],"produces":["*/*"],"parameters":[{"name":"m","in":"query","description":"m","required":true,"type":"ref"}],"responses":{"200":{"description":"OK","schema":{"type":"object","additionalProperties":{"type":"string"}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}}

When do i do codegen, it is able to generate the same erroneous method as i mentioned in (12), however it throws the following exception in the console:
>>

Auto Generated Inline Image 1
Auto Generated Inline Image 2

Dilip Krishnan

unread,
Sep 9, 2015, 8:33:09 PM9/9/15
to Swagger
Actually its perfectly legal per the spec. 

Map<String, Map<String, String>> is represented as 

{
  
"type": "object",
  "additionalProperties": {
    "$ref":"#/definitions/Map«string,string»"
  }
}

where "Map«string,string»" is

{
  
"type": "object",
  "additionalProperties": {
    "type": "string"
  }
}

Its no different from having a closed generic type 
class MapOfStringToString extends Map<String, String> {
  
}

and Map<String, MapOfStringToString> is represented as 

{
  "type": "object",
  "additionalProperties": {
    "$ref":"#/definitions/MapOfStringToString»"
  }
}

where "MapOfStringToString" is

{
  
"type": "object",
  "additionalProperties": {
    "type": "string"
  }
}


Now the symbols "«" and "»" might throw people off, but there is a thats a matter of configuring the rendering options.

Best
=Dilip
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggersocket+unsub...@googlegroups.com.

Dilip Krishnan

unread,
Sep 9, 2015, 8:43:42 PM9/9/15
to Swagger
To clarify what I meAn by rendering options. In springfox we have a switch when you configure the spring integration plugin that will make the type names code generation friendly.

```Java
...
.forCodeGeneration(true); // will not render the symbols
...

```

Amit Bansal

unread,
Sep 10, 2015, 6:27:36 AM9/10/15
to Swagger
Hi Dilip,

Can you simply tell me if there is way to generate the spec the way swagger-codegen expects ? Probably, its the best if you we continue this discussion in https://github.com/springfox/springfox/issues/956.

William,
I figured out issue (13). I manually added the reference for "System.Runtime.Serialization", and it removed all the compilation issue. I think its better if the dll is generated as part of codegen itself.

For (14), the problem is, it is not even generating the C# code for the method "getMap". I was wrong previously where i said it is generating. Please look into this. I have to use the "RequestParam" annotation as i want that the params are passed to the server as part query params.


Thanks,
Amit
Reply all
Reply to author
Forward
0 new messages