0

I'm making a json out of a class in c# and for making the json smaller i want to replace the string keys with numbers which correspond to a number of enums. an example would be a json the looks like this:

{
"initdata": 
{
"cell": {
  "apn": "n",
  "userName": "n",
  "password": "n",
  "number": "n"
},
"wifi": {
  "mode": "AP",
  "ssid": "m",
  "password": ","
},
"ports": {
  "p1": "k",
  "p2": "y",
  "p3": "5"
}
}

and enums that looks like this :

public enum celle { apn, userName, password, number };
public enum wifie { mode, ssid, password };
public enum portse { p1, p2, p3 };
public enum initdatae { cell , wifi , ports};
public enum settingse { initdata, timers }

and then I want the json to look like this :

{
"0": 
{
"0": {
  "0": "n",
  "1": "n",
  "2": "n",
  "3": "n"
},
"1": {
  "0": "AP",
  "1": "m",
  "2": ","
},
"2": {
  "0": "k",
  "1": "y",
  "2": "5"
}
}

Thanks

2 Answers2

1

If you are using Json.Net, for renaming the properties names, take a look here for exemple (there is plenty on Stack Overflow): Overwrite Json property name in c#

And for the values, I suggest you assign an int to each enum :

public enum celle 
{
     apn = 0, 
     userName = 1, 
     password = 2, 
     number = 3 
};

And then you cast the enum to an int to get the value before converting it to json:

int celleValue = (int)celle.userName;

So, in the end your class will look like something like this:

public class ClassToConvert()
{
    [JsonIgnore] // this property will not be on the json
    public celle celleValue {get;set;}
    [JsonProperty(PropertyName = "c1")]
    public int celleShort
    {
        get
        {
            return (int)this.celleValue;
        }
    }
}

public enum celle 
{
     apn = 0, 
     userName = 1, 
     password = 2, 
     number = 3 
};
Community
  • 1
  • 1
Matthieu Charbonnier
  • 2,794
  • 25
  • 33
0

If you don't have POCO's defined for your input JSON, you may rename your properties as follows:

  • deserialize the input JSON into an ExpandoObject
  • rename the ExpandoObject's properties as desired
  • serialize the ExpandoObject back to JSON:
public static void Main(string[] args)
{
    var json = @"{
        ""initdata"":  {
            ""cell"": {
                ""apn"": ""n"",
                ""userName"": ""n"",
                ""password"": ""n"",
                ""number"": ""n""
            },
            ""wifi"": {
                ""mode"": ""AP"",
                ""ssid"": ""m"",
                ""password1"": "",""
            },
            ""ports"": {
                ""p1"": ""k"",
                ""p2"": ""y"",
                ""p3"": ""5""
            }
        }
    }";
    dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(json, new ExpandoObjectConverter());
    PrepareEnumIds();
    RenameEnumProps(obj as ExpandoObject);
    var shortJson = JsonConvert.SerializeObject(obj, Formatting.Indented);
    Console.WriteLine(shortJson);
}

public static void RenameEnumProps(ExpandoObject expando)
{
    var expandoDict = expando as IDictionary<string, object>;
    var props = new List<string>(expandoDict.Keys);
    for (var i = props.Count - 1; i >= 0; i--)
    {
        var child = expandoDict[props[i]];
        if (child is ExpandoObject)
            RenameEnumProps(child as ExpandoObject);
        if (enumIds.ContainsKey(props[i]))
        {
            expandoDict.Add(enumIds[props[i]], child);
            expandoDict.Remove(props[i]);
        }
    }
}

static Dictionary<string, string> enumIds = new Dictionary<string, string>();

static void PrepareEnumIds()
{
    foreach (var enumType in new[] { typeof(celle), typeof(wifie), typeof(portse), typeof(initdatae), typeof(settingse) })
        foreach (var enumValue in Enum.GetValues(enumType))
            enumIds.Add(enumValue.ToString(), ((int)enumValue).ToString());
}

public enum celle { apn, userName, password, number };
public enum wifie { mode, ssid, password1 };
public enum portse { p1, p2, p3 };
public enum initdatae { cell, wifi, ports };
public enum settingse { initdata, timers }

Demo: https://dotnetfiddle.net/IPqxEQ

Note: I've cheated a little bit by changing one of the passwords values to make all enum values unique, sorry. This made renaming implementation significantly easier. But this does not affect the main point of implementation. I'll provide a complete implementation when I'll have some more spare time.

Dmitry Egorov
  • 9,542
  • 3
  • 22
  • 40