Jesper Lund Stocholm
Jesper Lund Stocholm

Reputation: 2013

Name of first property in JSON

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

Answers (2)

Pavel Anikhouski
Pavel Anikhouski

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

Roman Ryzhiy
Roman Ryzhiy

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

Related Questions