I am new to C# and have been struggling with this one problem for a few days. The API looks like this:
{
"data": [
{
"id": "1730938253104377856",
"user_id": "6c61d88c-7ff3-4cf1-b5cf-b05cc954d96b",
"type": "security",
"action": "user_switching_success",
"entity_id": null,
"ip_address": "xxxxx",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0",
"occurred_at": "2023-12-02T13:13:33Z",
"created_at": "2023-12-02T13:13:33Z",
"data": {
"metadata": null,
"target_uid": "c0eb0826-891f-4ea9-9d52-f2aba0cbc390",
"occurred_at": "2023-12-02T13:13:33.399598788Z",
"authentication_id": "",
"has_authenticated": true
},
"old_data": null
},
{
"id": "1730938253158903808",
"user_id": "c0eb0826-891f-4ea9-9d52-f2aba0cbc390",
"type": "security",
"action": "signin",
"entity_id": null,
"ip_address": "xxxxxx",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0",
"occurred_at": "2023-12-02T13:13:33Z",
"created_at": "2023-12-02T13:13:33Z",
"data": {
"metadata": null,
"occurred_at": "2023-12-02T13:13:33.402810919Z",
"captcha_verified": true,
"authentication_id": ""
},
"old_data": null
}
]
}
I have tried several variations of this code using Restsharp or Newtonsoft.json. I can get the "data" node back as one continuous string, but nothing I have tried has worked to get an array of the attributes populated so that I can use them in my program. I have seen dozens of examples of non-nested JSON, but I can't get the nested part to work. I really only need user_id, created_at, and action.
using RestSharp;
using System.Text.Json;
using System.Text.Json.Nodes;
class Program
{
static void Main()
{
string apiUrl = "https://xxxx/auditlog_events";
// Make the REST API request
var restClient = new RestClient(apiUrl);
var request = new RestRequest("");
request.AddHeader("accept", "application/json");
request.AddHeader("authorization", "Bearer xxxx");
var response = restClient.Execute(request);
// Check if the request was successful
if (response.IsSuccessful)
{
// Parse the JSON response into an array
var jsonArray = JsonSerializer.Deserialize<JsonNode>(response.Content!)!;
//var jsonArray = JsonSerializer.Deserialize<dataList>(response.Content!)!;
// Process the array
//Console.WriteLine(jsonArray);
Console.WriteLine("{0}", jsonArray["data"]);
//Console.WriteLine(jsonArray["type"]);
//Console.WriteLine(jsonArray["action"]);
}
else
{
Console.WriteLine($"Error: {response.ErrorMessage}");
}
}
}
public class dataList
{
public List<dataContainer> data;
}
public class dataContainer
{
public data data;
}
public class data {
public int id { get; set; }
public string user_id { get; set; }
public string type { get; set; }
public string action { get; set; }
public string entity_id { get; set; }
public string ip_address { get; set; }
public string user_agent { get; set; }
public string occured_at { get; set; }
public string created_at { get; set; }
public string data { get; set; }
public string old_data { get; set; }
}
I was expecting to get attribute values in an array that I could use. I got one continuous string or null lists.
Your property mapping isn't correct. I fixed few issues for you and this works:
public class dataContainer
{
public List<dataOuter> data { get; set; }
}
public class dataOuter
{
public string id { get; set; }
public string user_id { get; set; }
public string type { get; set; }
public string action { get; set; }
public string entity_id { get; set; }
public string ip_address { get; set; }
public string user_agent { get; set; }
public string occured_at { get; set; }
public string created_at { get; set; }
public dataInner data { get; set; }
public string old_data { get; set; }
}
public class dataInner
{
public string metadata { get; set; }
public string target_uid { get; set; }
public string occurred_at { get; set; }
public string authentication_id { get; set; }
public bool has_authenticated { get; set; }
}
Use this to deserialize:
dataContainer jsonArray = JsonSerializer.Deserialize<dataContainer>(response.Content!)!;
Also there is an issue converting the value in id to integer, I changed to string for now to get deserialize to work, but you can deal with the issue separately.
One more thing, as you are new to C#, the standard for public properties is for them to start with Capital case, so they would be Id, User_Id, Action, etc.