【问题标题】:insert json jObject data into labels and textboxes将 json jObject 数据插入标签和文本框
【发布时间】:2014-08-05 08:37:30
【问题描述】:

我的问题如下:

我创建了一个 Public sub,目前看起来像这样:

Public Sub eniroContacts()
        Dim phone As String = newCustPhone1.text
        Dim url As String = "http://bedrift.telefonkatalogen.no/tk/search.php?qry=" + phone + "&from=1&to=27&format=json&username=user&password=pw"
        Dim request As HttpWebRequest = DirectCast(WebRequest.Create(url), HttpWebRequest)
        Dim response As HttpWebResponse = DirectCast(request.GetResponse(), HttpWebResponse)
        Dim reader As StreamReader = New StreamReader(response.GetResponseStream())
        Dim o As JObject = JObject.Parse(reader.ReadToEnd)

        lblMsg.Text = o.ToString

        reader.Close()
        response.Close()
    End Sub

到目前为止一切顺利,我的 lblMsg.Text 显示了我想要从中获取数据的 json 字符串(为清晰起见已格式化):

{
    "qry": "92020945",
    "result": {
        "hitLinesBeforeFilter": 1,
        "userID": 299228,
        "1": {
            "listing": {
                "table": "listing",
                "id": "3647950",
                "duplicates": [{
                    "table": "listing",
                    "id": "3647950:0",
                    "idlinje": "E19CMOD",
                    "tlfnr": "99887766",
                    "etternavn": "Omnes",
                    "fornavn": "Martin",
                    "veinavn": "Highway",
                    "husnr": "20",
                    "postnr": "0601",
                    "virkkode": "P",
                    "apparattype": "M",
                    "telco": "TM",
                    "kilde": "E",
                    "bkdata": "M",
                    "prioritet": "0",
                    "fodselsdato": "1976-07-03",
                    "kommunenr": "301",
                    "poststed": "Oslo",
                    "kommune": "Oslo",
                    "fylke": "Oslo",
                    "landsdel": "Ø"
                }]
            }
        },
        "dummy": null
    }
}

我现在想要做的是实际获取字符串中的一些值并将它们放入我的一些文本框和标签中,但不知道我该怎么做。例如,我想要值“fornavn”、“tlfnr”和“fylke”。本例中的值为 Martin、99887766 和 Oslo,应分别放在 textbox1、2 和 3 中。

我还想补充一点,有些字段可能在某些搜索中不存在,例如名字(在我的示例中为“fornavn”)。当这不存在时,我尝试写作:

 Dim fornavn = o("result")("1")("listing")("duplicates")(0)("fornavn")

它崩溃了。在这些情况下我可以做些什么来防止这种情况发生?

非常感谢任何线索和提示! :)

【问题讨论】:

    标签: asp.net json vb.net


    【解决方案1】:

    最简单的方法是直接使用属性名称和数组索引(来自json.net docs)。像这样的:

    Dim fornavn = o("result")("1")("listing")("duplicates")(0)("fornavn")
    

    看起来响应中的结果和重复项的数量会在不同的响应之间发生变化,因此您可能无法像那样对其进行硬编码(例如,您可能需要先检查结果是否至少包含一个项目并且并且重复项至少有一项)

    另一种方法是将字符串反序列化为强类型的 .Net 对象。您将创建镜像 json 结构的 .Net 类,并告诉 json.net 将 json 字符串转换为这些类的 .Net 对象实例。请参阅json.net docs。这需要更多的工作,因为您需要创建 .Net 类,并且您需要了解反序列化过程。如果您想探索此选项,请查看thisthis other 问题。

    编辑

    鉴于 json 结构,在 json 对象的 result 属性中手动获取诸如“1”之类的属性可能会更容易。 然后,您可以选择手动继续钻取对象并迭代重复项,应用您需要的任何逻辑,或反序列化为 .Net 对象。

    以下代码将获取 result 属性,使用键 1,2 等迭代其所有属性,并使用这两种方法在每个副本中打印名称:

    Sub Main()
        Dim JsonStr = "... the json string ..."     
    
        Dim o As JObject = JObject.Parse(JsonStr)
        Dim results = o("result")
        For Each resultProperty In results.Value(Of JObject)()
            'Only get properties like "1" inside the root "result" property
            If Not Integer.TryParse(resultProperty.Key, Nothing) Then Continue For
    
            'Approach 1: Manually Iterate over the duplicates array inside each result
            Dim duplicatesArray = resultProperty.Value("listing")("duplicates").Value(Of JArray)()
            For Each duplicate In duplicatesArray
                'Make sure there is a fornavn property
                If duplicate("fornavn") Is Nothing Then Continue For
                Console.WriteLine(duplicate("fornavn"))
            Next
    
            'Approach 2: Deserialize the listing into a .Net object
            Dim serializer As JsonSerializer = New JsonSerializer()
            Dim resultObject As Result = JsonConvert.DeserializeObject(Of Result)(resultProperty.Value.ToString())
            For Each duplicateObject In resultObject.listing.duplicates
                Console.WriteLine(duplicateObject.fornavn)
            Next
        Next
    
        Console.ReadKey()
    End Sub
    
    Class Result
        Property listing As Listing
    End Class
    
    Class Listing
        Property table As String
        Property id As String
        Property duplicates As Duplicate()
    End Class
    
    Class Duplicate
        Property table As String
        Property id As String
        Property idlinje As String
        Property fornavn As String
        'Continues with all the other properties...
    End Class
    

    请注意,我刚刚快速编写了这段代码,因此如果某些属性并不总是出现在 json 响应中,您可能需要对其进行调整。

    【讨论】:

    • 当您说结果和重复项可以超过 1 次命中时,您是正确的。真的可以从 0 到 10 以上。
    • 我用第一种方法得到了结果,但需要验证是否有比 1 更多的结果和重复项。这样做最简单的方法是什么?我也试图研究反序列化,但目前它看起来让我很困惑。我创建了这些类,但不知道如何使用它们。如果需要,我可以添加它们,但是我在创建它们时得到的字符串很长。
    • 非常感谢您为我编写所有这些代码。我已经看过它并将尝试方法 2 开始。我看到代码本身运行良好! :) 再次感谢您抽出时间在这件事上帮助我!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-22
    • 2011-05-05
    • 1970-01-01
    • 2013-03-27
    • 1970-01-01
    • 2015-09-23
    相关资源
    最近更新 更多