1

Can we parse a dynamic JSON to a List of Object List<DiffModel>

public class DiffModel 
{
  public string Property { get; set; }
  public string OldValue { get; set; }
  public string NewValue { get; set; }
} 

The JSON is generated with the help of a library which helps to compare 2 JSON objects and find out the differences. The differences are getting stored as a JToken

Sample JSON JToken value generated with help of JToken patch = jdp.Diff(left, right) method

{
  "Id": [
    78485,
    0
  ],
  "ContactId": [
    767304,
    0
  ],
  "TextValue": [
    "text value",
    "text14"
  ],
  "PostCode": [
    null
  ]
}

From the JSON the value of first item in the object is

DiffModel [0] =  Property ="id" OldValue="78485" NewValue="0"
DiffModel [1] =  Property ="contactId" OldValue="767304" NewValue="0"
DiffModel [2] =  Property ="TextValue" OldValue="text value" NewValue="text14"
DiffModel [3] =  Property ="PostCode" OldValue= null NewValue=null

Can we navigate between the properties of dynamic JSON and build a similar model

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
Sebastian
  • 4,625
  • 17
  • 76
  • 145
  • 1
    For your particular case, you could use `patch.AsJEnumerable().OfType().Select(p=>new DiffModel { ... })`. However, the returned `JToken` isn't as simple as your example. You can read the [full specs](https://github.com/benjamine/jsondiffpatch/blob/master/docs/deltas.md). – weichch Nov 11 '21 at 08:57

1 Answers1

4

You can define a data model like this:

struct DiffModel
{
    public string Property { get; init; }
    public object OldModel { get; init; }
    public object NewModel { get; init; }
}

I've used struct but you can use class, record whatever you prefer.

Then you can convert the JToken to a Dictionary<string, object[]>.

  • The key will be the property name
  • the value will be the property values
var rawModel = patch.ToObject<Dictionary<string, object[]>>();

Finally, all you need is a mapping between the DiffModel and the KeyValuePair<string, object[]>:

var diffModels = rawModel
    .Select(pair => new DiffModel
    {
        Property = pair.Key,
        OldModel = pair.Value.First(),
        NewModel = pair.Value.Last(),
    }).ToArray();
Peter Csala
  • 17,736
  • 16
  • 35
  • 75
  • Error: Newtonsoft.Json.JsonSerializationException: Error converting value " to type 'System.Collections.Generic.Dictionary`2[System.String,System.Object[]]'. Path ''. ---> System.ArgumentException: Could not cast or convert from System.String to System.Collections.Generic.Dictionary`2[System.String,System.Object[]]. This is the error i was getting – Sebastian Nov 11 '21 at 09:44
  • @Sebastion I've used your json as an input for my conversion (`JToken patch = JObject.Parse(json)`). I haven't experienced that problem which has been mentioned by you. But let me double check. – Peter Csala Nov 11 '21 at 09:52
  • @Sebastian I could not reproduce your exception. Could you please share in your question your `left` and `right` variables to be able to generate the diff on my local machine as well? – Peter Csala Nov 11 '21 at 09:59
  • The value of patch is like below { "Id": [ 78487, 0 ], "ContactId": [ 767304, 0 ], "TextValue": [ "scs re gregre", "asdas" ] } – Sebastian Nov 11 '21 at 11:24
  • @Sebastian I've copy-pasted your above sample json and it works fine. You can check it here as well: https://dotnetfiddle.net/g0jt3z – Peter Csala Nov 11 '21 at 11:48
  • 1
    My bad The initial step of parsing the string to JSON was missing in my code block . Looks like this is working in normal use cases. I have to debug further to see how its handling the null values [ either in new or old value section ] – Sebastian Nov 11 '21 at 11:58