15

According to http://www.newtonsoft.com/json/help/html/PopulateObject.htm you can update an existing instance by values defined in a JSON-string. My problem is that the data I have to populate the object has already been parsed into a JToken object. My current approach looks something like this:

Private Sub updateTarget(value As JToken, target as DemoClass)
    Dim json As String = value.ToString(Formatting.None) 
    JsonConvert.PopulateObject(json, target)
End Sub

Is there a better way to accomplish this without having to "revert" the parsing that was already done when creating the JToken in the first place?

mike
  • 1,627
  • 1
  • 14
  • 37

1 Answers1

24

Use JToken.CreateReader() and pass the reader to JsonSerializer.Populate. The reader returned is a JTokenReader which iterates through the pre-existing JToken hierarchy instead of serializing to a string and parsing.

Since you tagged your question c#, here's a c# extension method that does the job:

public static class JsonExtensions
{
    public static void Populate<T>(this JToken value, T target) where T : class
    {
        using (var sr = value.CreateReader())
        {
            JsonSerializer.CreateDefault().Populate(sr, target); // Uses the system default JsonSerializerSettings
        }
    }
}

And the equivalent in VB.NET:

Public Module JsonExtensions

    <System.Runtime.CompilerServices.Extension> 
    Public Sub Populate(Of T As Class)(value As JToken, target As T)
        Using sr = value.CreateReader()
            ' Uses the system default JsonSerializerSettings
            JsonSerializer.CreateDefault().Populate(sr, target)
        End Using
    End Sub

End Module 
dbc
  • 104,963
  • 20
  • 228
  • 340
  • Yes, that _is_ indeed the correct c#>vb translation. Works like a charm! Thank you! – mike May 15 '15 at 16:26
  • 1
    To improve a little bit, you can get the serializer as an argument with the default value of null then use the default serializer if null – Sean Ed-Man Sep 26 '20 at 13:54