将json字符串数组反序列化为字符串数组

时间:2014-04-15 20:12:00

标签: c# dynamic json.net

让我们假设我有以下JSON对象:

{
    "Key": "\"QTuY+0m31w2QiZGl4h+W8w==\"",
    "Value":
    [
        "addgroup",
        "viewgroup",
        "editgroup"
    ]
}

如何在C#Value中反序列化string[]部分?

问题是,string[]不是Value部分中唯一的类型,它可以是一切,所以我需要使用动态。

我正在使用JSON.net,当我使用JsonConvert.DeserializeObject方法时,我得到了一个运行时绑定程序异常。

这是我用来反序列化的方法:

public async Task<Tuple<string, dynamic>> ReadCachingEntryAsync(string uri) {
    var data = tools.ReadEntry(Path.Combine(cacheFolder, uri.Replace("/", "")));
    var res = new Tuple<string, dynamic>(string.Empty, null);
    if (data != null) {
        var dat = JsonConvert.DeserializeObject<KeyValuePair<string, dynamic>>(UTF8Encoding.UTF8.GetString(data));
        res = new Tuple<string, dynamic>(dat.Key, dat.Value);
    }
    return res;
}

tools.ReadEntry(data)从二进制格式化文件中返回包含数据的byte[]

这是班级KeyValuePair<K, V>

[Serializable]
internal struct KeyValuePair<K, V> {
    public K Key { get; set; }
    public V Value { get; set; }
}

2 个答案:

答案 0 :(得分:2)

只需使用要将输入字符串反序列化的类型调用DeserializeObject<T>替换T,json.NET将负责其余的工作。

string[] json = JsonConvert.DeserializeObject<string[]>(inputString);

编辑:

好的,假设您的所有json都是在EDIT 3中发布的示例的形式,那么您真正想要的是;

public class KVPair
{
    public string Key { get; set; }
    public string[] Value { get; set; }
}

KVPair pair = JsonConvert.DeserializeObject<KVPair>(UTF8Encoding.UTF8.GetString(data));

现在这是相当静态的,但我不确定你真的需要动态。如果您这样做,那么您希望Value属性的类型为objectdynamic。但是,如果你走那条路,那么你将不得不处理这种未知类型。我真的不了解dynamic类型,所以我不能评论如何在以后处理它,但如果说例如,数组可能包含,整数,浮点数或字符串而你使Value类型为object,您将在稍后检查数组,确定基础类型并将每个项目转换为该类型,然后才能对它们执行任何有用的操作。希望有所帮助。如果您很幸运,您只能使用我在上面发布的代码,因为它更简单,实际上是类型安全的。

答案 1 :(得分:2)

您可以检查它是否为JArray并实施特殊处理。 E.g。

byte[] data = Encoding.UTF8.GetBytes(@"{""Key"": ""Something"", ""Value"": [""test"", ""test 2"", ""test 3""]}");
var dat = JsonConvert.DeserializeObject<KeyValuePair<string, dynamic>>(UTF8Encoding.UTF8.GetString(data));
var value = dat.Value;
if (value is JArray)
{
    var arrayType = value[0].Value.GetType().MakeArrayType();
    value = value.ToObject(arrayType);
}
var res = new Tuple<string, dynamic>(dat.Key, value);