Felix
Felix

Reputation: 10078

How do I convert enum to int in Dictionary key in .NET Core Web API

Suppose I have an enum

public enum Countries {
    France, GreatBritain, Japan, CostaRica, ...
}

And suppose I have the following action in WebApi Controller

[HttpGet]
public ActionResult<Dictionary<Countries, int> Get() {
   return new Dictionary<Countries, int> {
      [Countries.France] = 10,
      [Countries.CostaRica] = 50
      ...
   }
}

JSON that goes to the client is "France": 10, "CostaRica": 50, etc.

I would very much prefer to have 0: 10, 4: 50 instead. Client has no knowledge of the enum values; only the integer index and description (like "France" or "Costa Rica"). I am seeding the database using same enum - so I am confident that IDs match.

I tried different JsonConverter options, but they all seem to assume scalar value.

Note: this is a simplified example; real business application is much more complex. Obviously, there is a big benefit to use enum on the server without creating Dictionary<int, int> and casting all keys before returning to client. I am pretty sure Json.NET can convert it - I just can figure how to help it.

My application is .NET Core 2.2; so is this example. I know that 3.0 handles Json.Net slightly differently; but I don't think this converting issue is version-dependent

Upvotes: 1

Views: 1433

Answers (1)

iSR5
iSR5

Reputation: 3498

It's a matter of casting to int, and return the ActionResult<Dictionary<int, int>> which would be something like this :

[HttpGet]
public ActionResult<Dictionary<int, int>> Get() {
   return new Dictionary<Countries, int> {
      [Countries.France] = 10,
      [Countries.CostaRica] = 50
      ...
   }.ToDictionary(x => (int)x.Key, x => x.Value);
}

UPDATE

Just want to share this, if you need to convert any Enum to a Dictionary using Reflection, you can do something like this :

public Dictionary<string, object> GetEnumAsDictionary<TEnum>() where TEnum : System.Enum
{
    var result = new Dictionary<string, object>();

    var _fields = typeof(TEnum).GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);

    for (int i = 0; i < _fields.Length; i++)
    {
        result.Add(_fields[i].Name, _fields[i].GetRawConstantValue());
    }

    return result;
}

usage :

var enDic = GetEnumAsDictionary<Countries>();

GetRawConstantValue returns object that's why I made the dictionary value type as an object. but it's easy to bind it to other datatypes or making it generic.

I thought this would be useful to share.

Upvotes: 2

Related Questions