vb.net - JSON.Net - 反序列化对象格式

标签 vb.net json json.net

我正在使用 JSON.Net 尝试反序列化来自 SurveyGizmo 的一些调查响应。 这是我正在读取的数据的快照:

{"result_ok":true,
"total_count":"44",
"page":1,
"total_pages":1,
"results_per_page":50,
"data":[
        {"id":"1",
        "contact_id":"",
        "status":"Complete",
        "is_test_data":"0",
        "datesubmitted":"2011-11-13 22:26:53",
        "[question(59)]":"11\/12\/2011",
        "[question(60)]":"06:15 pm",
        "[question(62)]":"72",
        "[question(63)]":"One",
        "[question(69), option(10196)]":"10",

我已经按照提交日期设置了一个类,但考虑到问题数量会发生变化,我不确定如何设置该类来反序列化问题?我还需要捕获该选项(如果存在)。

我使用此代码来使用 JSON.NET 反序列化功能:

Dim responses As Responses = JsonConvert.DeserializeObject(Of Responses)(fcontents)

类(class):

Public Class Responses
    Public Property result_OK As Boolean

    Public Property total_count As Integer

    Public Property page As Integer

    Public Property total_pages As Integer

    Public Property results_per_page As Integer

    Public Overridable Property data As List(Of surveyresponse)
End Class

Public Class SurveyResponse
    Public Property id As Integer

    Public Property status As String

    Public Property datesubmitted As Date
End Class

最佳答案

支持完全疯狂映射的技巧是使用 JsonConverter 并完全替换该对象的解析,(我为 C# 表示歉意,但我不擅长 VB 语法):

class Program
{
    static void Main(string[] args)
    {
        var result = JsonConvert.DeserializeObject<Responses>(TestData);
    }

    const string TestData = @"{""result_ok"":true,
""total_count"":""44"",
""page"":1,
""total_pages"":1,
""results_per_page"":50,
""data"":[
    {""id"":""1"",
    ""contact_id"":"""",
    ""status"":""Complete"",
    ""is_test_data"":""0"",
    ""datesubmitted"":""2011-11-13 22:26:53"",
    ""[question(59)]"":""11\/12\/2011"",
    ""[question(60)]"":""06:15 pm"",
    ""[question(62)]"":""72"",
    ""[question(63)]"":""One"",
    ""[question(69), option(10196)]"":""10"",
}]}";
}

[JsonObject]
class Responses
{
    public bool result_ok { get; set; }
    public string total_count { get; set; }
    public int page { get; set; }
    public int total_pages { get; set; }
    public int results_per_page { get; set; }
    public SurveyResponse[] Data { get; set; }
}

[JsonObject]
// Here is the magic: When you see this type, use this class to read it.
// If you want, you can also define the JsonConverter by adding it to
// a JsonSerializer, and parsing with that.
[JsonConverter(typeof(DataItemConverter))]
class SurveyResponse
{
    public string id { get; set; }
    public string contact_id { get; set; }
    public string status { get; set; }
    public string is_test_data { get; set; }
    public DateTime datesubmitted { get; set; }
    public Dictionary<int, string> questions { get; set; }
}

class DataItemConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(SurveyResponse);
    }

    public override bool CanRead
    {
        get { return true; }
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var value = (SurveyResponse)existingValue;
        if (value == null)
        {
            value = new SurveyResponse();
            value.questions = new Dictionary<int, string>()
        }

        // Skip opening {
        reader.Read();

        while (reader.TokenType == JsonToken.PropertyName)
        {
            var name = reader.Value.ToString();
            reader.Read();

                // Here is where you do your magic
            if (name.StartsWith("[question("))
            {
                int index = int.Parse(name.Substring(10, name.IndexOf(')') - 10));
                value.questions[index] = serializer.Deserialize<string>(reader);
            }
            else
            {
                var property = typeof(SurveyResponse).GetProperty(name);
                property.SetValue(value, serializer.Deserialize(reader, property.PropertyType), null);
            }

            // Skip the , or } if we are at the end
            reader.Read();
        }

        return value;
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

现在显然您还需要做更多的事情才能使其真正强大,但这为您提供了如何做到这一点的基础知识。如果您只需要更改属性名称(JsonPropertyAttribute 或重写 DefaultContractResolver.ResolvePropertyName()),还有更轻量级的替代方案,但这为您提供了完全控制权。

关于vb.net - JSON.Net - 反序列化对象格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8252176/

相关文章:

vb.net - 即使在 VB2005 项目中添加 System.Management 引用后,仍未定义 ManagementObjectSearcher

vb.net - Visual Studio 2012/Windows Phone 8 从异步 Web 服务获取结果

java - 使用 Gson 抛出异常反序列化多态 JSON

c# - 使用 LINQ 创建 JSON 异常

c# - 如何使用 JSON.NET 解析递归数据结构?

.net - Dim X as New Y vs. Dim X as Y = New Y()

mysql - vb net max_user_connections 到 mysql

Android Json 解析与 Gson

javascript - 从 json_encode 脚本创建不带双引号的数组

c# - 我可以选择在运行时关闭 JsonIgnore 属性吗?