Skip to content
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

What's the propper way to handle enum flags? #657

Open
paulomorgado opened this issue Mar 7, 2017 · 1 comment
Open

What's the propper way to handle enum flags? #657

paulomorgado opened this issue Mar 7, 2017 · 1 comment

Comments

@paulomorgado
Copy link
Contributor

paulomorgado commented Mar 7, 2017

What I expect/want is for this:

[Flags]
public enum Directions
{
    Up = 1,
    Down = 2,
    Left = 4,
    Right = 8,
}

public class Request
{
    Directions Directions {get; set; }
}

public void SetAvailableDirections(Request request)
{
    // ...
}

To generate a swagger specification where the Directions property allows multiple values (array with collectionFormat set to csv ???) but not needing the Directions property to be an array.

JsonConvert.SerializeObject(Directions.Up | Directions.Right, new StringEnumConverter(true)) already outputs the correct value: "up, right"

I tried to generate a client from this swagger:

{
  "consumes": [
    "application/json"
  ],
  "produces": [
    "application/json"
  ],
  "paths": {
    "/api/SetAvailableDirections": {
      "post": {
        "operationId": "SetAvailableDirections",
        "parameters": [
          {
            "name": "request",
            "in": "body",
            "schema": {
              "$ref": "#/definitions/Request"
            },
            "x-nullable": true
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        }
      }
    },
  },
  "definitions": {
    "Request": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "Directions": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Directions"
          },
          "collectionFormat": "csv"
        }
      }
    },
    "Directions" : {
      "type": "string",
      "x-enumNames": [
        "Up",
        "Down",
        "Left",
        "Right"
      ],
      "enum": [
        "Up",
        "Down",
        "Left",
        "Right"
      ],
      "description": ""
    }
  },
  "parameters": {},
  "responses": {},
}

and it generates this:

[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "8.8.6270.12833")]
public partial class Request 
{
    [Newtonsoft.Json.JsonProperty("Directions", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore, ItemConverterType = typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
    public System.Collections.Generic.List<Directions> Directions { get; set; }

    public string ToJson() 
    {
        return Newtonsoft.Json.JsonConvert.SerializeObject(this);
    }
    
    public static Request FromJson(string data)
    {
        return Newtonsoft.Json.JsonConvert.DeserializeObject<Request>(data);
    }
}

[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "8.8.6270.12833")]
public enum Directions
{
    [System.Runtime.Serialization.EnumMember(Value = "Up")]
    Up = 0,

    [System.Runtime.Serialization.EnumMember(Value = "Down")]
    Down = 1,

    [System.Runtime.Serialization.EnumMember(Value = "Left")]
    Left = 2,

    [System.Runtime.Serialization.EnumMember(Value = "Right")]
    Right = 3,

}

which I don't think complies to the swagger specification because this:

sonConvert.SerializeObject(new Request { Directions = new List<Directions> { Directions.Up, Directions.Right } }, new StringEnumConverter(true))

yields this:

{"Directions":["Up","Right"]}

If I change the code to:

public partial class Request
{
    [Newtonsoft.Json.JsonProperty("Directions", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore, ItemConverterType = typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
    public Directions Directions { get; set; }

    public string ToJson()
    {
        return Newtonsoft.Json.JsonConvert.SerializeObject(this);
    }

    public static Request FromJson(string data)
    {
        return Newtonsoft.Json.JsonConvert.DeserializeObject<Request>(data);
    }
}

[Flags]
public enum Directions
{
    [System.Runtime.Serialization.EnumMember(Value = "Up")]
    Up = 1,

    [System.Runtime.Serialization.EnumMember(Value = "Down")]
    Down = 2,

    [System.Runtime.Serialization.EnumMember(Value = "Left")]
    Left = 4,

    [System.Runtime.Serialization.EnumMember(Value = "Right")]
    Right = 8,
}

for this:

JsonConvert.SerializeObject(new Request { Directions = Directions.Up | Directions.Right }, new StringEnumConverter(true))

I get this:

{"Directions":"up, right"}

Which is what I was expecting from that swagger.

@RicoSuter
Copy link
Owner

See RicoSuter/NJsonSchema#226

@RicoSuter RicoSuter changed the title What's the propper way to handle enm flags? What's the propper way to handle enum flags? Mar 14, 2017
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