用对应于枚举的数字替换json中的键

时间:2017-04-27 12:55:59

标签: c# json enums

我正在用c#中的一个类创建一个json,并且为了使json更小,我想用对应于多个枚举的数字替换字符串键。 一个例子是json,看起来像这样:

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

和枚举看起来像这样:

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 }

然后我希望json看起来像这样:

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

由于

2 个答案:

答案 0 :(得分:1)

如果您使用的是Json.Net,要重命名属性名称,请查看此处的示例(Stack Overflow上有很多内容):Overwrite Json property name in c#

对于值,我建议你为每个枚举分配一个int:

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

然后将枚举转换为int以获取值,然后将其转换为json:

int celleValue = (int)celle.userName;

所以,最后你的课将看起来像这样:

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 
};

答案 1 :(得分:0)

如果您没有为输入JSON定义POCO,则可以按如下方式重命名您的属性:

  • 将输入JSON反序列化为ExpandoObject
  • 根据需要重命名ExpandoObject的属性
  • ExpandoObject序列化为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 }

演示:https://dotnetfiddle.net/IPqxEQ

注意:我已经通过更改其中一个password的值来欺骗了一点,以使所有枚举值都是唯一的,抱歉。这使重命名实现变得更加容易。但这并不影响实施的主要方面。当我有更多的业余时间时,我会提供完整的实施。