Reputation: 2013
I am querying a REST endpoint for data. The result can be one of two kinds of documents
In simplified versions, these are
1.
{
"Feature": {
"CreationDate": "2018-07-12T09:22:37.068Z",
"_CreatedAt": "Jul 12, 2018",
"ObjectID": 236769828012,
"ObjectUUID": "5a4fa66b-a81b-48c3-afdc-b7ad8c4d4d1b",
"VersionId": "36",
}
}
{
"Initiative": {
"CreationDate": "2018-07-12T09:22:37.068Z",
"_CreatedAt": "Jul 12, 2018",
"ObjectID": 236769828012,
"ObjectUUID": "5a4fa66b-a81b-48c3-afdc-b7ad8c4d4d1b",
"VersionId": "36",
}
}
So the structure of the documents are identical - apart from the first property - which I do not now at runtime.
My question:
How do I get the value for that property?
My code to extract simply uses the Newtonsoft component to deserialize the result from the API into a dynamic
construct.
static void GetItemByProject(string projectId)
{
//var uri = ...;
response = GetData(uri);
dynamic itemData = JsonConvert.DeserializeObject(response.Result);
}
static async Task<string> GetData(string uri)
{
return await client.GetStringAsync(uri);
}
static readonly HttpClient client = new HttpClient();
I know that I can use reflection or cast the result of the DeSerializeObject-method to a Dictionary<string, dynamic>
result and iterate over the keys, but that seems really cumbersome.
Is there a more elegant way to do what I want?
Upvotes: 1
Views: 235
Reputation: 23258
You may use Json.Linq
for that, just get the first property and deserialize its value
var result = JObject.Parse(response.Result);
var value = result.Properties().FirstOrDefault()?.Value.ToObject<Response>();
Where Response
class can be the following (just an example, you can use any model that you want)
public class Response
{
public DateTime CreationDate { get; set; }
public string _CreatedAt { get; set; }
public long ObjectID { get; set; }
public string ObjectUUID { get; set; }
public string VersionId { get; set; }
}
Upvotes: 3
Reputation: 1656
Assuming we have
public class Root
{
public FeatureOrInitiative Feature { get; set; }
public FeatureOrInitiative Initiative { get; set; }
public static Root FromJson(string json) => JsonConvert.DeserializeObject<Root>(json);
}
public class FeatureOrInitiative
{
[JsonProperty("CreationDate")]
public DateTimeOffset CreationDate { get; set; }
[JsonProperty("_CreatedAt")]
public string CreatedAt { get; set; }
[JsonProperty("ObjectID")]
public long ObjectId { get; set; }
[JsonProperty("ObjectUUID")]
public Guid ObjectUuid { get; set; }
[JsonProperty("VersionId")]
public long VersionId { get; set; }
}
This is it, actually. We just call our Deserializer and get what we need for both variants:
Root itemData = Root.FromJson(response.Result);
// Feature or Initiative is null
Upvotes: 0