15

From the result of an API call I have a large amount of JSON to process.

I currently have this

Object convertObj = JsonConvert.DeserializeObject(responseFromServer);

I am aware that I could do something like

Movie m = JsonConvert.DeserializeObject<Movie>(responseFromServer);

And then use it like

m.FieldName
m.AnotherField
//etc

Ideally I would like to do something like

var itemName = convertObj["Name"];

to get the first Name value for the first item in the list.

Is this possible, or do I have to create a class to deserialize to?

The reason I do not want to create the class is I am not the owner of the API and the field structure may change.

Edit.

Okay so I created the class as it seems the best approach, but is there a way to deserialize the JSON into a list?

var sessionScans = new List<SessionScan>();
sessionScans = JsonConvert.DeserializeObject<SessionScan>(responseFromServer);

Complains that it cannot convert SessionScan to generic list.

andrewb
  • 2,995
  • 7
  • 54
  • 95
  • u can use `Dynamic` but it is not recommended. – Mohit S Nov 22 '16 at 04:30
  • Possible duplicate of [Deserialize JSON into C# dynamic object?](http://stackoverflow.com/questions/3142495/deserialize-json-into-c-sharp-dynamic-object) – Davatar Nov 22 '16 at 04:32
  • @MohitShrivastava why is it *not recommended* ? – Jim Nov 22 '16 at 04:49
  • Possible duplicate of [Deserialize json object into dynamic object using Json.net](http://stackoverflow.com/questions/4535840/deserialize-json-object-into-dynamic-object-using-json-net) – Jim Nov 22 '16 at 04:54
  • @Jim bcoz dynamic typing is that it often hides bugs that would be otherwise revealed during compilation. Such bug then only manifests on run-time, which of course makes it much harder to detect. – Mohit S Nov 22 '16 at 04:56
  • @MohitShrivastava yes I agree completely with you. On the other side, the question essentially is *Deserializing JSON response without creating a class*. – Jim Nov 22 '16 at 04:59

7 Answers7

18

No need to use dynamic, you can simply use JToken which is already does what you expect:

var json = @"
    {
        ""someObj"": 5
    }
";
var result = JsonConvert.DeserializeObject<JToken>(json);
var t = result["someObj"]; //contains 5
Rob
  • 26,989
  • 16
  • 82
  • 98
10

With .NET 6, this can be done as below,

using System.Text.Json;
using System.Text.Json.Nodes;

string jsonString = @"some json string here";

JsonNode forecastNode = JsonNode.Parse(jsonString)!;

int temperatureInt = (int)forecastNode!["Temperature"]!;
Console.WriteLine($"Value={temperatureInt}");

//for nested elements, you can access as below
int someVal = someNode!["someParent"]["childId"]!.ToString();

Refer this MS docs page for more samples - create object using initializers, make changes to DOM, deserialize subsection of a JSON payload.

Anand Sowmithiran
  • 2,591
  • 2
  • 10
  • 22
5

You can try with JObject.Parse :

dynamic convertObj = JObject.Parse("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");

string name = convertObj.Name;
string address = convertObj.Address.City;
Yanga
  • 2,885
  • 1
  • 29
  • 32
2

The below example can deserialize JSON to a list of anonymous objects using NewtonSoft.Json's DeserializeAnonymousType method.

var json = System.IO.File.ReadAllText(@"C:\TestJSONFiles\yourJSONFile.json");
var fooDefinition = new { FieldName = "", AnotherField = 0 }; // type with fields of string, int
var fooListDefinition = new []{ fooDefinition }.ToList();

var foos = JsonConvert.DeserializeAnonymousType(json, fooListDefinition);
Ash K
  • 1,802
  • 17
  • 44
0

You can use Json.NET's LINQ to JSON API

JObject o = JObject.Parse(jsonString);
string prop = (string)o["prop"];
Frank Fajardo
  • 7,034
  • 1
  • 29
  • 47
0

Use Newtonsoft.Json

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

var json = "[{'a':'aaa','b':'bbb','c':'ccc'},{'a':'aa','b':'bb','c':'cc'}]";
var ja = (JArray)JsonConvert.DeserializeObject(json);
var jo = (JObject) ja[0];
Console.WriteLine(jo["a"]);
GlitterX
  • 16
  • 2
0

I had this problem working with unknown APIs then I decide to come over this problem using this approach, I'm writing down here my test case:

            [TestMethod]
        public void JsonDocumentDeserialize()
        {
            string jsonResult = @"{
""status"": ""INTERNAL_SERVER_ERROR"",
    ""timestamp"": ""09-09-2019 11:00:24"",
    ""message"": ""documentUri is required.""
}";

            var jDoc = JsonDocument.Parse(jsonResult);
            if (jDoc.RootElement.TryGetProperty("message", out JsonElement message))
            {
                Assert.IsTrue(message.GetString() == "documentUri is required.");
            }
        }

it worked for me because first I was looking to find a way to use dynamic type as it's mentioned in Azure Function HTTPTrigger. But I found this approach most useful and robust.

Microsoft Reference

Nader Vaghari
  • 141
  • 10