0

Need help to deserialize complex json file using Visual Basic and Newtonsoft.Json library. Here is the sample of Json file:

{
"value":  [
              {
                  "Id":  12345,
                  "Name":  "Test",
                  "CardCount":  0,
                  "DailySpendLimit":  0.00,
                  "WeeklySpendLimit":  50.00,
                  "MonthlySpendLimit":  100.00,
                  "YearlySpendLimit":  1000.00,
                  "LifetimeSpendLimit":  0.00,                      
                  "MerchantCategories":  [
                                             "@{Id=11111; Name=Associations \u0026 Organizations; Description=Post Office, local and federal government services, religious organizations.; TransactionLimit=0.00; DailySpendLimit=0.00; WeeklySpendLimit=0.00; MonthlySpendLimit=0.00; YearlySpendLimit=0.00; LifetimeSpendLimit=0.00}",
                                             "@{Id=22222; Name=Automotive Dealers; Description=Vehicle dealerships (car, RV, motorcycle, boat, recreational).; TransactionLimit=0.00; DailySpendLimit=0.00; WeeklySpendLimit=0.00; MonthlySpendLimit=0.00; YearlySpendLimit=0.00; LifetimeSpendLimit=0.00}"                                              
                                         ]
              }
          ],
"Count":  1

}

I had setup classes:

Public Class TEST_AdvRules
<JsonProperty("value")>
Public Property ValueDetails As ValueList()
Public Class ValueList
    <JsonProperty("Id")>
    Public Property RuleId As Integer
    <JsonProperty("Name")>
    Public Property RuleName As String = ""
    Public Property CardCount As Integer
    Public Property DailySpendLimit As Double
    Public Property WeeklySpendLimit As Double
    Public Property MonthlySpendLimit As Double
    Public Property YearlySpendLimit As Double
    Public Property LifetimeSpendLimit As Double
    <JsonProperty("MerchantCategories")>
    Public Property MerchantCategories() As List(Of MerchantCategoriesList)       
End Class
Public Class MerchantCategoriesList
    Public Property Id As Integer
    Public Property Name As String = ""
    Public Property Description As String = ""
    Public Property TransactionLimit As Double
    Public Property DailySpendLimit As Double
    Public Property WeeklySpendLimit As Double
    Public Property MonthlySpendLimit As Double
    Public Property YearlySpendLimit As Double
    Public Property LifetimeSpendLimit As Double
End Class

End Class

The code for deserilization:

Dim jsonStringP = IO.File.ReadAllText(PathJson & SecFileName)
    Dim serSettings = New JsonSerializerSettings()
    serSettings.ContractResolver = New CamelCasePropertyNamesContractResolver()

    Dim RulesPEX = JsonConvert.DeserializeObject(Of TEST_AdvRules)(jsonStringP, serSettings)

But it errors out on the deserialization line - can't convert MerchantCategories. I have never dealt with Json with [ "@ array sequence. Am I processing it wrong? Also - there is a character sequence '\u0026 ' within Merchant categories. Does it require special handling? Thank you!

3 Answers 3

1

The problem is that MerchantCategories is a string collection. You will have to convert each string to object using a custom string analyzer. Last time I worked with Vb.net was more then 10 years ago, so I can give you a solution in C# , your part would be to convert it to VB.Net. I don't feel like installing VB.NET compilliar at my mashine.

using Newtonsoft.Json;

var jsonObject = JObject.Parse(jsonStringP);
var jsonArr=new JArray();
    
    foreach (var item in   (JArray) jsonObject["value"][0]["MerchantCategories"])
    {
        jsonArr.Add(ConvertToJObject(item.ToString()));
    }
    jsonObject["value"][0]["MerchantCategories"]=jsonArr;
    TEST_AdvRules RulesPEX = jsonObject.ToObject<TEST_AdvRules>();

this function converts a string to a JObject

public JObject ConvertToJObject(string str)
{
    var strStart=str.IndexOf("{")+1;
    var strEnd=str.IndexOf("}")-2;
    var arr = str.Substring(strStart, strEnd).Split(";").Select(c => c.Split("="));
    var jObj = new JObject();
    foreach (var item in arr)
        jObj.Add(new JProperty(item[0].Trim(), item[1].Trim()));

    return jObj;
}
Sign up to request clarification or add additional context in comments.

12 Comments

I think jobject is not the thing, he wants... Anyway, if the json is given, then he has to deserialize it separatedly into his type.
@dba result is not jobject , result is TEST_AdvRules
sorry, missed the conversion. :-) still, I think it's not a "clean" serialization that way. would fail if the payload is different in the string-array
@dba Any Json is a string, so any payload will fail, if the class is not right
I'm with you, I just wanted to point it out for this particular situation.
|
1

let Visual Studio create the class for you:

  • copy the whole json file content to the clipboard
  • in VS, add a new empty class -> Edit -> Paste Special -> paste json as class

I tend to add a shared Read-Method for easier construction. Of course you can rename your classes as you wish :-)

I'm on german VS but you get the idea :-)

enter image description here

enter image description here

11 Comments

Interesting. My Visual Studio doesn't have option to add/generate Json class. I'll try your suggestion with Read function and let you know. Thanks
you may need to add a VS-Component: see here
Thank you. Will do. I modified the code, but it still can't read MerchantCategories - "Newtonsoft.Json.JsonReaderException: 'Unexpected character encountered while parsing value: [. Path 'value[0].MerchantCategories', line 24, position 46.". Plus in the code above there is no way to get details for MerchantCategories. Shouldn't there be another class for it?
Public Property MerchantCategories() As List(Of MerchantCategoriesList) means Array(of List(of yourType)) - change to Public Property MerchantCategories() As MerchantCategoriesList, OR Public Property MerchantCategories As List(Of MerchantCategoriesList) (BTW the Type shouldn't be called "List", since its an object)
Public Property ValueDetails As ValueList() -> Public Property ValueDetails() As ValueList and you miss the Count property on your root class
|
1

Translating Serge's answer into VB (note untested code so it's possible there are some minor errors)...

Imports Newtonsoft.Json

'...

Dim jsonObject = JObject.Parse(jsonStringP)
Dim jsonArr = new JArray()

For Each item In CType(jsonObject("value")(0)("MerchantCategories"), JArray)
    jsonArr.Add(ConvertToJObject(item.ToString()))
Next

jsonObject("value")(0)("MerchantCategories") = jsonArr
Dim RulesPEX As TEST_AdvRules = jsonObject.ToObject(Of TEST_AdvRules)()

and

Public Function ConvertToJOBject(ByVal str As String) As JObject
    Dim strStart = str.IndexOf("{") + 1
    Dim strEnd = str.IndexOf("}") - 2

    Dim arr = str.Substring(strStart, strEnd).Split(";").Select(Function(c) c.Split("="))
    Dim jObj = New JObject()

    For Each item In arr
        jObj.Add(New JProperty(item(0).Trim(), item(1).Trim()))
    Next

    Return jObj
End Function

4 Comments

Wonderful! Will test it today
Had to modify it slightly - had to specify Linq.JArray for JArray; Linq.JObject etc and add a condition for json files that had no Merchant Categories at all, but all works great!
@Alla Please feel free to edit the answer (if the queue isn't full) to reflect any syntax fixes, I'll accept the edit. If you had to use Linq.JArray etc. that would suggest that there is a missing Imports statement.
Correct. Since it was just 3 places I needed to add Linq, I chose that strategy instead of Imports. And the que is full unfortunately. Thanks again for your 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.