2

ANSWER given describes using LINQ to JSON and the JObject to convert from JSON to a workable object on the fly. Below is the completed code that takes me from my JSON to a workable object, followed by the original question.

            'Parse string of JSON data into a JObject that can be accessed via VB.NET
            Dim resultSet As JObject = JObject.Parse(responseBody)

            'Data can be accessed as seen below
            Dim cpu As String = CType(resultSet("KeyName"), String)

=========================================================================

I have a web app that will be making several API calls to a service called inContact (http://www.incontact.com/)

Each of the API calls will be receiving an HTTP response filled with JSON formatted in this way:

    {
  "resultSet": {
    "_links": {
      "self": "string",
      "next": "string",
      "previous": "string"
    },
    "businessUnitId": 0,
    "lastPollTime": "2016-11-08T21:45:46.510Z",
    "totalRecords": 0,
    "agents": [
      {
        "agentId": 0,
        "userName": "string",
        "firstName": "string",
        "middleName": "string",
        "lastName": "string",
        "emailAddress": "string",
        "isActive": true,
        "teamId": 0,
        "teamName": "string",
        "reportToId": 0,
        "reportToName": "string",
        "isSupervisor": true,
        "lastLogin": "2016-11-08T21:45:46.510Z",
        "lastUpdated": "2016-11-08T21:45:46.510Z",
        "location": "string",
        "custom1": "string",
        "custom2": "string",
        "custom3": "string",
        "custom4": "string",
        "custom5": "string",
        "internalId": "string",
        "profileId": 0,
        "profileName": "string",
        "timeZone": "string",
        "country": "string",
        "countryName": "string",
        "state": "string",
        "city": "string",
        "chatRefusalTimeout": 0,
        "phoneRefusalTimeout": 0,
        "workItemRefusalTimeout": 0,
        "defaultDialingPattern": 0,
        "defaultDialingPatternName": "string",
        "teamDefaultMaxChats": true,
        "maxConcurrentChats": 0,
        "notes": "string",
        "createDate": "2016-11-08T21:45:46.510Z",
        "inactiveDate": "2016-11-08T21:45:46.510Z",
        "hireDate": "2016-11-08T21:45:46.510Z",
        "terminationDate": "2016-11-08T21:45:46.510Z",
        "rehireStatus": true,
        "employmentType": 0,
        "employmentTypeName": "Full-Time",
        "referral": "string",
        "atHome": true,
        "hiringSource": "string",
        "ntLoginName": "string",
        "scheduleNotification": "5",
        "federatedId": "string",
        "sipUser": "string",
        "useTeamMaxEmailInboxCount": true,
        "maxEmailInboxCount": 0
      }
    ]
  }
}

I am deserializing the JSON with Newtonsoft. However, with each different call there will be different key/value pairs, such as this:

{
  "resultSet": {
    "businessUnitId": 0,
    "lastPollTime": "2016-11-08T21:45:46.604Z",
    "teams": [
      {
        "teamId": 0,
        "teamName": "string",
        "isActive": true,
        "description": "string",
        "notes": "string",
        "lastUpdateTime": "2016-11-08T21:45:46.604Z",
        "inViewEnabled": true,
        "wfoEnabled": true,
        "wfmEnabled": true,
        "qmEnabled": true,
        "maxConcurrentChats": 0,
        "agentCount": 0,
        "maxEmailInboxCount": true,
        "inViewGamificationEnabled": true,
        "inViewChatEnabled": true,
        "inViewLMSEnabled": true,
        "analyticsEnabled": true
      }
    ],
    "agents": [
      {
        "agentId": 0,
        "firstName": "string",
        "lastName": "string"
      }
    ]
  }
}

I currently am taking in the HTTP response and deserializing the JSON to create a workable .NET object. To do so this is my shortened code, omitting the HTTP request, assuming the request was successful:

        If Not String.IsNullOrEmpty(responseBody) Then
            ' Success. Do something with the response.
            'Declare object for holding the JSON from the API call for this call only (class does not fit other calls)
            Dim resultSet As GetAgentsAPICall = New GetAgentsAPICall
            'Deserialize JSON response into the new resultSet object
            resultSet = JsonConvert.DeserializeObject(responseBody)

The issue is that I need a specific class for each API call, instead of just being able to take a string with JSON formatting and throw it into an object with properties matching the key/values. Below is the class I have that takes in just the above API call (the first one listed, longer in length):

Public Class GetAgentsAPICall
    Public Property resultSet As Resultset
End Class

Public Class Resultset
        Public Property _links As _Links
        Public Property businessUnitId As Integer
        Public Property lastPollTime As Date
        Public Property totalRecords As Integer
        Public Property agents() As Agent
    End Class

    Public Class _Links
        Public Property self As String
        Public Property _next As String
        Public Property previous As String
    End Class

    Public Class Agent
        Public Property agentId As Integer
        Public Property userName As String
        Public Property firstName As String
        Public Property middleName As String
        Public Property lastName As String
        Public Property emailAddress As String
        Public Property isActive As Boolean
        Public Property teamId As Integer
        Public Property teamName As String
        Public Property reportToId As Integer
        Public Property reportToName As String
        Public Property isSupervisor As Boolean
        Public Property lastLogin As Date
        Public Property lastUpdated As Date
        Public Property location As String
        Public Property custom1 As String
        Public Property custom2 As String
        Public Property custom3 As String
        Public Property custom4 As String
        Public Property custom5 As String
        Public Property internalId As String
        Public Property profileId As Integer
        Public Property profileName As String
        Public Property timeZone As String
        Public Property country As String
        Public Property countryName As String
        Public Property state As String
        Public Property city As String
        Public Property chatRefusalTimeout As Integer
        Public Property phoneRefusalTimeout As Integer
        Public Property workItemRefusalTimeout As Integer
        Public Property defaultDialingPattern As Integer
        Public Property defaultDialingPatternName As String
        Public Property teamDefaultMaxChats As Boolean
        Public Property maxConcurrentChats As Integer
        Public Property notes As String
        Public Property createDate As Date
        Public Property inactiveDate As Date
        Public Property hireDate As Date
        Public Property terminationDate As Date
        Public Property rehireStatus As Boolean
        Public Property employmentType As Integer
        Public Property employmentTypeName As String
        Public Property referral As String
        Public Property atHome As Boolean
        Public Property hiringSource As String
        Public Property ntLoginName As String
        Public Property scheduleNotification As String
        Public Property federatedId As String
        Public Property sipUser As String
        Public Property useTeamMaxEmailInboxCount As Boolean
        Public Property maxEmailInboxCount As Integer
End Class

I'm trying to avoid having 20 or 30 similar lengthy classes prebuilt, and instead build a modifiable list or object on the fly. I will need to take the values and either store them in a database or modify them and use another API call to POST the values back. Does anyone have a best practice, or am I stuck with 20-30 huge class definitions?

Thanks for your time!

1 Answer 1

3

Parse it with a JObject, which can also be queried using LINQ (see Newtonsoft's LINQ to JSON API, which sits under the Newtonsoft.Json.Linq namespace):

JObject o = JObject.Parse(@"{
    'CPU': 'Intel',
    'Drives': [
        'DVD read/writer',
         '500 gigabyte hard drive'
     ]
}");

string cpu = (string)o["CPU"];
// Intel

string firstDrive = (string)o["Drives"][0];
// DVD read/writer

IList<string> allDrives = o["Drives"].Select(t => (string)t).ToList();
// DVD read/writer
// 500 gigabyte hard drive

The example is in C#, but you can find relevant VB.NET answers on StackOverflow (have a look at the answer here, for example).

Sign up to request clarification or add additional context in comments.

2 Comments

Exactly what I needed, a method to parse it into a generalized object that can then be accessed and manipulated. Thanks trashr0x
Glad I could help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.