-1

I have the following JSON Code retrieved from: https://urlscan.io/api/v1/search/?q=page.domain:google.nl&size=1

{
  "results": [
    {
      "task": {
        "visibility": "public",
        "method": "automatic",
        "domain": "secureauverificationn.de",
        "apexDomain": "secureauverificationn.de",
        "time": "2022-07-12T09:01:23.794Z",
        "source": "certstream-suspicious",
        "uuid": "01a2f1ac-97c5-4377-8d95-b77095e6e78f",
        "url": "https://secureauverificationn.de"
      },
      "stats": {
        "uniqIPs": 6,
        "uniqCountries": 1,
        "dataLength": 493720,
        "encodedDataLength": 170314,
        "requests": 11
      },
      "page": {
        "country": "DE",
        "server": "gws",
        "redirected": "off-domain",
        "ip": "2a00:1450:4001:82f::2003",
        "mimeType": "text/html",
        "title": "Google",
        "url": "https://www.google.nl/",
        "tlsValidDays": 83,
        "tlsAgeDays": 35,
        "tlsValidFrom": "2022-06-06T10:32:16.000Z",
        "domain": "www.google.nl",
        "umbrellaRank": 8162,
        "apexDomain": "google.nl",
        "asnname": "GOOGLE, US",
        "asn": "AS15169",
        "tlsIssuer": "GTS CA 1C3",
        "status": "200"
      },
      "_id": "01a2f1ac-97c5-4377-8d95-b77095e6e78f",
      "sort": [
        1657616483794,
        "01a2f1ac-97c5-4377-8d95-b77095e6e78f"
      ],
      "result": "https://urlscan.io/api/v1/result/01a2f1ac-97c5-4377-8d95-b77095e6e78f/",
      "screenshot": "https://urlscan.io/screenshots/01a2f1ac-97c5-4377-8d95-b77095e6e78f.png"
    }
  ],
  "total": 10000,
  "took": 13,
  "has_more": true
}

I want to get the value inside the results array:

"result": "https://urlscan.io/api/v1/result/01a2f1ac-97c5-4377-8d95-b77095e6e78f/",

This is the code I already have, but I stumble on the GetProperty because the next property is an array.

        public static async Task<String> GetSearchResults(string url)
        {
            url = url.Replace("http://", "").Replace("https://", "");
            string finalurl = "https://urlscan.io/api/v1/search/?q=page.domain:" + url + "&size=1";
            var options = new RestClientOptions(finalurl)
            {
                ThrowOnAnyError = true,
                Timeout = -1
            };
            var client = new RestClient(options);
            var request = new RestRequest(finalurl, Method.Get);
            RestResponse response = await client.ExecuteAsync(request);
            String output = response.Content;
            var JsonObject = JsonDocument.Parse(output);
            var RootElement = JsonObject.RootElement;
            var NewObject = RootElement.GetProperty("results").ToString();
            Console.WriteLine(NewObject);
            return output;
        }

My question is how to retrieve the value from the nested array in the most simple way. I do not want to use Newtonsoft as I am using the System.Text.Json library.

What I do want is the following:

  • Get the result value and save it to a string the easiest way possible
  • A working example eventually that either iterates through an array or gets the values inside an array with system.text.json
  • Why not create DTOs and deserialize the string directly to objects? – Panagiotis Kanavos Jul 12 '22 at 13:13
  • It's easy to convert that JSON into DTOs using eg an online converter or Visual Studio's `Paste Special > Paste JSON as Classes`. Once you have the classes, you can reduce your code to `HttpClient client=new HttpClient();.... var root=await client.GetFromJsonAsync(url);` where `Root` is the root DTO and use the `Root.Results` array. – Panagiotis Kanavos Jul 12 '22 at 13:23
  • Do you have an example for me? Because I am not familiar with DTO's :) – Leonardo van de Weteringh Jul 12 '22 at 13:24
  • Classes. Just classes. DTO means Data Transfer Objects. Just create classes that match your JSON. The main job of both System.Text.Json and JSON.NET is to deserialize JSON into classes. The docs for both libraries start from this. Check eg [How to serialize and deserialize JSON](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-how-to?pivots=dotnet-6-0) – Panagiotis Kanavos Jul 12 '22 at 13:25
  • I have looked into it, but I still have not clue how to do it. Do you have an example for me. I do have to get the data from a rest client. The problem is that the first property can be chosen, but the property behind is an array and inside that array there is a property I want to choose as displayed above. That property I want to save into an string. – Leonardo van de Weteringh Jul 12 '22 at 13:47
  • I already posted a link to the docs. The very first deserialization example shows how to read JSON contents as classes. – Panagiotis Kanavos Jul 12 '22 at 13:51
  • You can use a converter like eg https://json2csharp.com/ , paste your JSON and convert it to classes. The top-level class is `Root`. Once you have that, you can deserialize a string to a Root with `JsonSerializer.Deserialize(json)`. After that you're working with objects and arrays of objects – Panagiotis Kanavos Jul 12 '22 at 13:54
  • That worked! the json2csharp helped me to work it out. I will post the solution below in a bit. – Leonardo van de Weteringh Jul 12 '22 at 15:02

1 Answers1

-1

you could try using dynamic. Something like this should work (not tested in IDE):

var root = JsonObject.RootElement as dynamic;
var results = root.results as IEnumerable<dynamic>;
var firstResult = results.FirstOrDefault();
string resultUrl = firstResult.result as string;

Update:

let's ditch dynamic and use proper model classes then:


record Dto(ResultItem[] results);
record ResultItem(string result);

var deserializedJson = JsonSerializer.Deserialize<Dto>(json);
var firstResult = deserializedJson.results.FirstOrDefault();

of course I've omitted error checking.

David Guida
  • 950
  • 9
  • 19