一尘不染

如何使用非标准(和不同的)属性名称反序列化JSON(在.NET中)

json

我必须阅读一个JSON流(我无法控制),其形式为:

{"files":
    {
        "/some_file_path.ext": {"size":"1000", "data":"xxx", "data2":"yyy"},
        "/other_file_path.ext": {"size":"2000", "data":"xxx", "data2":"yyy"},
        "/another_file_path.ext": {"size":"3000", "data":"xxx", "data2":"yyy"},
    }
}

因此,我有一个名为的对象files,该对象具有多个属性,它们具有1)每次都有不同的名称,2)每次都有不同的名称,以及3)带有不能在C#属性中使用的字符的名称。

我该如何反序列化?

我将其放入可移植库中,因此无法在System.Web.Script.Serialization中使用JavaScriptSerializer,并且不确定JSON.NET。我希望使用标准的DataContractJsonSerializer。


更新:我已将示例数据更改为更接近实际数据,并更正了不重要的区域中的JSON语法。(仍然简化了很多,但是其他部分是相当标准的)


阅读 242

收藏
2020-07-27

共1个答案

一尘不染

您可以通过JSON属性名称将"files"对象建模为Dictionary键控:

public class RootObject
{
    public Dictionary<string, PathData> files { get; set; }
}

public class PathData
{
    public int size { get; set; }
    public string data { get; set; }
    public string data2 { get; set; }
}

然后, 仅当您使用.Net 4.5或更高版本时
,才可以使用进行反序列化DataContractJsonSerializer,但是必须首先设置DataContractJsonSerializerSettings.UseSimpleDictionaryFormat = true

        var settings = new DataContractJsonSerializerSettings { UseSimpleDictionaryFormat = true };
        var root = DataContractJsonSerializerHelper.GetObject<RootObject>(jsonString, settings);

使用辅助方法:

public static class DataContractJsonSerializerHelper
{
    public static T GetObject<T>(string json, DataContractJsonSerializer serializer = null)
    {
        using (var stream = GenerateStreamFromString(json))
        {
            var obj = (serializer ?? new DataContractJsonSerializer(typeof(T))).ReadObject(stream);
            return (T)obj;
        }
    }

    public static T GetObject<T>(string json, DataContractJsonSerializerSettings settings)
    {
        return GetObject<T>(json, new DataContractJsonSerializer(typeof(T), settings));
    }

    private static MemoryStream GenerateStreamFromString(string value)
    {
        return new MemoryStream(Encoding.Unicode.GetBytes(value ?? ""));
    }
}

或者,您可以安装Json.NET并执行以下操作:

        var root = JsonConvert.DeserializeObject<RootObject>(jsonString);

Json.NET会自动将字典序列化为JSON对象,而无需更改设置

2020-07-27