Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net JSON.Net-反序列化对象格式_Vb.net_Json_Json.net - Fatal编程技术网

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

Vb.net JSON.Net-反序列化对象格式,vb.net,json,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":"

我正在使用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",
到datesubmitted为止,我已经设置了一个类,但是我不确定如何设置该类来反序列化问题,因为问题的数量将发生变化?我还需要捕获选项(如果存在)

我使用以下代码来使用JSON.NET反序列化函数:

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

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语法):

类程序
{
静态void Main(字符串[]参数)
{
var result=JsonConvert.DeserializeObject(TestData);
}
常量字符串TestData=@“{”结果\确定“:true,
“总数”:“44”,
“第”页:1,
“总页数”:1,
“每页的结果”:50,
“数据”:[
{“id”:“1”,
“联系人id:”“”,
“状态”:“完成”,
“”是测试数据“”:“”0“”,
“datesubmitted”:“2011-11-13 22:26:53”,
[问题(59)]:“11\/12\/2011”,
[问题(60)]:“下午6时15分”,
[问题(62)]:“72”,
[问题(63)]:“一”,
“[问题(69),选项(10196)]:”“10”,
}]}";
}
[JsonObject]
班级反应
{
公共bool result_ok{get;set;}
公共字符串总计数{get;set;}
公共整型页{get;set;}
公共int总页数{get;set;}
公共int结果每_页{get;set;}
公共调查响应[]数据{get;set;}
}
[JsonObject]
//神奇之处在于:当您看到这种类型时,使用这个类来阅读它。
//如果需要,还可以通过将JsonConverter添加到
//JsonSerializer,并使用它进行解析。
[JsonConverter(类型(DataItemConverter))]
班级调查响应
{
公共字符串id{get;set;}
公共字符串联系人_id{get;set;}
公共字符串状态{get;set;}
公共字符串是_test_data{get;set;}
public DateTime datesubmitted{get;set;}
公共词典问题{get;set;}
}
类DataItemConverter:JsonConverter
{
公共覆盖布尔CanConvert(类型objectType)
{
返回objectType==typeof(SurveyResponse);
}
公共覆盖布尔可读取
{
获取{return true;}
}
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
var值=(SurveyResponse)现有值;
如果(值==null)
{
值=新的SurveyResponse();
value.questions=newdictionary()
}
//跳开{
reader.Read();
while(reader.TokenType==JsonToken.PropertyName)
{
var name=reader.Value.ToString();
reader.Read();
//这是你施展魔法的地方
if(name.StartsWith(“[问题(”))
{
int index=int.Parse(name.Substring(10,name.IndexOf('))-10));
value.questions[index]=序列化程序.反序列化(读取器);
}
其他的
{
var property=typeof(SurveyResponse).GetProperty(name);
SetValue(值,序列化程序.反序列化(读取器,property.PropertyType),null);
}
//跳过,或者}如果我们在末尾
reader.Read();
}
返回值;
}
公共覆盖布尔可写
{
获取{return false;}
}
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
抛出新的NotImplementedException();
}
}

现在很明显,要使它真正健壮,您还需要做很多事情,但这为您提供了如何做到这一点的基础知识。如果您只需要更改属性名称(无论是
JsonPropertyAttribute
还是重写
DefaultContractResolver.ResolvePropertyName(),都有更多轻量级的替代方案
,但这可以让你完全控制。

西蒙,我感谢你在回复中付出的努力!起初我对回复感到有点害怕,我希望它会很好而且简单!到目前为止效果还不错,但有选项的问题除外;“[问题(31),选项(10019)]:“39.99”,值得注意的是这个问题(31)可能有多个选项响应。所以我想我需要开始捕获问题id、选项id和值,但我不认为我可以用字典来实现这一点?我想我已经对它进行了排序。我将很快发布我的更改。是的,这只是让你知道如何覆盖属性名->对象更新过程,我不想猜测选项()的含义是什么:)
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();
    }
}