【问题标题】:JSON: Error when converting to dictionary?JSON:转换为字典时出错?
【发布时间】:2018-02-18 04:36:57
【问题描述】:

我在将 JSON 转换为字典时遇到问题,谁能帮忙?

04:33:25 - 加载配置时出错。 System.InvalidCastException: 无法将“System.Int64”类型的对象转换为“System.String”类型。 在 Seegal.Core.Extentions.JsonExtensions.ToFlatDictionary(JToken 令牌,字符串路径)在 C:\Users\admin\workspace\Seegal\Seegal\Seegal\Core\Extentions\JsonExtentions.cs:line 28 在 Seegal.Core.Extentions.JsonExtensions.c.b__0_0(JProperty x) 在 C:\Users\admin\workspace\Seegal\Seegal\Seegal\Core\Extentions\JsonExtentions.cs:line 19 在 System.Linq.Enumerable.d__172.MoveNext() at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable1 源,Func2 keySelector, Func2 elementSelector, IEqualityComparer1 comparer) at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable1 源,Func2 keySelector, Func2 elementSelector)在 Seegal.Core.Extentions.JsonExtensions.ToFlatDictionary(JToken token, 字符串路径)在 C:\Users\admin\workspace\Seegal\Seegal\Seegal\Core\Extentions\JsonExtentions.cs:line 18 点 Seegal.Core.Extentions.JsonExtensions.c.b__0_0(JProperty x) 在 C:\Users\admin\workspace\Seegal\Seegal\Seegal\Core\Extentions\JsonExtentions.cs:line 19 在 System.Linq.Enumerable.d__172.MoveNext() at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable1 源,Func2 keySelector, Func2 elementSelector, IEqualityComparer1 comparer) at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable1 源,Func2 keySelector, Func2 elementSelector)在 Seegal.Core.Extentions.JsonExtensions.ToFlatDictionary(JToken token, 字符串路径)在 C:\Users\admin\workspace\Seegal\Seegal\Seegal\Core\Extentions\JsonExtentions.cs:line 18 点 Seegal.Core.Extentions.JsonExtensions.c.b__0_0(JProperty x) 在 C:\Users\admin\workspace\Seegal\Seegal\Seegal\Core\Extentions\JsonExtentions.cs:line 19 在 System.Linq.Enumerable.d__172.MoveNext() at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable1 源,Func2 keySelector, Func2 elementSelector, IEqualityComparer1 comparer) at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable1 源,Func2 keySelector, Func2 elementSelector)在 Seegal.Core.Extentions.JsonExtensions.ToFlatDictionary(JToken token, 字符串路径)在 C:\Users\admin\workspace\Seegal\Seegal\Seegal\Core\Extentions\JsonExtentions.cs:line 18 在 Seegal.Core.Config.ConfigHandler.Load(String apiUrl) 中 C:\Users\admin\workspace\Seegal\Seegal\Seegal\Core\Config\ConfigHandler.cs:line 49

我要转换成字典的 JSON:

{
    "bingo": {
        "ftp" : {
            "host" : "",
            "port" : 21,
            "username" : "",
            "password" : "",
            "enabled" : 0,
        }
    },

    "snowman": {
        "sockets" : {
            "host" : "127.0.0.1",
            "port" : 2000,
        }
    }
}

方法:

public static class JsonExtensions
{
    public static Dictionary<string, string> ToFlatDictionary(this JToken token, string path = null)
    {
        switch (token.Type)
        {
            case JTokenType.Object:
                return token.Children<JProperty>()
                    .SelectMany(x => x.Value.ToFlatDictionary(x.Name))
                    .ToDictionary(x => path == null ? x.Key : string.Join(".", path, x.Key), x => x.Value);

            case JTokenType.Array:
                return token
                    .SelectMany((x, i) => x.ToFlatDictionary(i.ToString()))
                    .ToDictionary(x => path == null ? x.Key : string.Join(".", path, x.Key), x => x.Value);

            default:
                return new Dictionary<string, string>
                {
                    [path] = (string)((JValue)token).Value
                };
        }
    }
}

转换行,发生错误的行:

_configElements = JObject.Parse(responseText).ToFlatDictionary();

【问题讨论】:

    标签: c# .net json


    【解决方案1】:

    这可能是因为它似乎试图将 int64 值直接转换为字符串。如果你调整默认语句如下代码应该开始工作

                default:
                    return new Dictionary<string, string>
                    {
                        [path] = (((JValue)token).Value).ToString()
                    };
    

    一个更安全的选择是 convert.ToString 来防止 NULL 等。但是对于眼前的问题,不使用类型转换应该可以解决问题

    【讨论】:

      【解决方案2】:

      您的默认情况下的假设无效。一个值既不是数组也不是对象并不意味着它有一个为它的值定义的字符串转换。

      这是一个工作版本

      static Dictionary<string, string> ToFlatDictionary(this JToken token, string path = null)
      {
          switch (token)
          {
              case JObject jo: return jo.Properties()
                  .SelectMany(x => x.Value.ToFlatDictionary(x.Name))
                  .ToDictionary(x => path == null ? x.Key : $"{path}.{x.Key}", x => x.Value);
      
              case JArray ja: return ja
                  .SelectMany((x, i) => x.ToFlatDictionary(i.ToString()))
                  .ToDictionary(x => path == null ? x.Key : $"{path}.{x.Key}", x => x.Value);
      
              case var v when v != null: return new Dictionary<string, string>
              {
                  [path] = v.Value<string>()
              };
      
              default: return new Dictionary<string, string> { };
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-07-20
        • 1970-01-01
        • 2018-07-04
        • 2014-12-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多