Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
807 views
in Technique[技术] by (71.8m points)

c# - How do deserialize JSON with non-standard (and varying) property names (in .NET)

I have to read a JSON stream (which I have no control over), which is in the form:

{"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"},
    }
}

So, I have an object named files, which has a number of properties, which have 1) different names every time, 2) different number of them every time, and 3) names with characters which can't be used in C# properties.

How do I deserialize this?

I'm putting this into a Portable Library, so I can't use the JavaScriptSerializer, in System.Web.Script.Serialization, and I'm not sure about JSON.NET. I was hoping to use the standard DataContractJsonSerializer.


UPDATE: I've changed the sample data to be closer to the actual data, and corrected the JSON syntax in the area the wasn't important. (Still simplified quite a bit, but the other parts are fairly standard)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can model your "files" object as a Dictionary keyed by the JSON property name:

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

Then, only if you are using .Net 4.5 or later, you can deserialize using DataContractJsonSerializer, but you must first set DataContractJsonSerializerSettings.UseSimpleDictionaryFormat = true:

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

With the helper method:

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 ?? ""));
    }
}

Alternatively, you can install Json.NET and do:

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

Json.NET automatically serializes dictionaries to JSON objects without needing to change settings.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...