JSON:转换为字典时出错?

时间:2018-02-18 04:36:57

标签: c# .net json

我在将JSON转换为字典时遇到问题,有人可以帮忙吗?

  

04:33:25 - 加载配置时出错。 System.InvalidCastException:   无法将类型为“System.Int64”的对象强制转换为“System.String”。   在Seegal.Core.Extentions.JsonExtensions.ToFlatDictionary(JToken   令牌,字符串路径)   C:\ Users \用户管理\工作空间\ Seegal \ Seegal \ Seegal \核心\一些推广\ JsonExtentions.cs:线   28点   Seegal.Core.Extentions.JsonExtensions<> c.b__0_0(JProperty   x)in   C:\ Users \用户管理\工作空间\ Seegal \ Seegal \ Seegal \核心\一些推广\ JsonExtentions.cs:线   19在System.Linq.Enumerable.d__17 2.MoveNext() at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable 1   source,Func 2 keySelector, Func 2 elementSelector,   的IEqualityComparer 1 comparer) at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable 1   source,Func 2 keySelector, Func 2 elementSelector)at   Seegal.Core.Extentions.JsonExtensions.ToFlatDictionary(JToken令牌,   字符串路径)   C:\ Users \用户管理\工作空间\ Seegal \ Seegal \ Seegal \核心\一些推广\ JsonExtentions.cs:线   18点到   Seegal.Core.Extentions.JsonExtensions<> c.b__0_0(JProperty   x)in   C:\ Users \用户管理\工作空间\ Seegal \ Seegal \ Seegal \核心\一些推广\ JsonExtentions.cs:线   19在System.Linq.Enumerable.d__17 2.MoveNext() at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable 1   source,Func 2 keySelector, Func 2 elementSelector,   的IEqualityComparer 1 comparer) at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable 1   source,Func 2 keySelector, Func 2 elementSelector)at   Seegal.Core.Extentions.JsonExtensions.ToFlatDictionary(JToken令牌,   字符串路径)   C:\ Users \用户管理\工作空间\ Seegal \ Seegal \ Seegal \核心\一些推广\ JsonExtentions.cs:线   18点到   Seegal.Core.Extentions.JsonExtensions<> c.b__0_0(JProperty   x)in   C:\ Users \用户管理\工作空间\ Seegal \ Seegal \ Seegal \核心\一些推广\ JsonExtentions.cs:线   19在System.Linq.Enumerable.d__17 2.MoveNext() at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable 1   source,Func 2 keySelector, Func 2 elementSelector,   的IEqualityComparer 1 comparer) at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable 1   source,Func 2 keySelector, Func 2 elementSelector)at   Seegal.Core.Extentions.JsonExtensions.ToFlatDictionary(JToken令牌,   字符串路径)   C:\ Users \用户管理\工作空间\ Seegal \ Seegal \ Seegal \核心\一些推广\ JsonExtentions.cs:线   18在Seegal.Core.Config.ConfigHandler.Load(String apiUrl)in   C:\ Users \用户管理\工作空间\ Seegal \ Seegal \ Seegal \核心\配置\ ConfigHandler.cs:线   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();

2 个答案:

答案 0 :(得分:0)

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

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

更安全的替代方案是convert.ToString以防止NULL等。但对于眼前的问题,不使用类型转换应解决问题

答案 1 :(得分:0)

您的默认情况会产生无效假设。值既不是数组也不是对象,并不意味着它具有为其值定义的字符串转换。

这是一个工作版本

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