-1

I am working with an API that returns an array of "entries" records.

I would like to create a class definition that can be used to deserialize the entire json object.

I am hoping a library that would support this exists, I only tagged json.net as I have worked with it in the past. I'm open to anything.

One of the properties in each entry has a name that represents a consistent data structure, but has a different name each time. The property name does have a format that would easily be matched by a regular expression if that helps.

The property in question here is

"https://bi.com/biprws/v1/documents/1"

Where the trailing "/1" represents an id which will change with each record, and there will be property names like

"https://bi.com/biprws/v1/documents/1"
"https://bi.com/biprws/v1/documents/123"
"https://bi.com/biprws/v1/documents/12345"

etc

The json returned by the API with just a single record for brevity

"entries": [
    {
        "https://bi.com/biprws/v1/documents/1": {
            "__deferred": {
                "uri": "https://bi.com/biprws/v1/documents/1"
            }
        },
        "cuid": "x",
        "name": "x",
        "description": "",
        "id": "1",
        "type": "x",
        "ownerid": "1",
        "updated": "Jan 01, 2023 00:07 AM",
        "parentid": "1"
    },
]

I believe that my question is different than the one linked to this by a moderator, as the data schema is more complicated.

This post suggested by dbc in the comments was helpful to me. How to deserialize a child object with dynamic (numeric) key names?

It doesn't fully work as it fails to properly populate the value of the dynamic property, so its not necessarily going to be helpful to everyone, but in my case the dynamic property name is enough for me to work with.

Chris
  • 679
  • 1
  • 11
  • 26
  • Are you somehow bound to that format? For me it looks like you put a value (an id) as key of something. It feels wrong. – Ralf Mar 31 '23 at 15:20
  • Yes this is the format returned by the API over which I have no control – Chris Mar 31 '23 at 15:21
  • If there is no good way to do this, I can (theoretically) ignore the uri provided in that property and construct it manually using the "id" property, as I am assuming that is not going to change, but I was trying to avoid that since it could break. – Chris Mar 31 '23 at 15:23
  • If you can that would be good. But the "____deferred" key sound like something that can change. It has the vibe of a moved resource so may point to a different id and you maybe interested in that id. – Ralf Mar 31 '23 at 15:28
  • Hmm using a dictionary might work, good idea. I'll give that a shot – Chris Mar 31 '23 at 16:19
  • 1
    Your model has a mixture of fixed and dynamic property names. If values of the property names were also dynamic, you could use a `[JsonExtensionData]` dictionary as shown in [Deserialize json with known and unknown fields](https://stackoverflow.com/a/21763919/3744182). But it looks like your dynamic values are typed to be `string` (I.e. you have a `Dictionary` so does [How to deserialize a child object with dynamic (numeric) key names?](https://stackoverflow.com/a/40094403/3744182) answer your question? – dbc Mar 31 '23 at 17:08
  • 1
    Yes I think I can get that 2nd link to do what I want, ty! – Chris Mar 31 '23 at 19:01
  • I would look into `JsonConverter`. I recently gave an answer which shows the syntax, and there are lots of other examples. https://stackoverflow.com/questions/75841617/deserializing-a-mixed-collection-of-strings-and-objects-with-json-net/75841793#75841793 – Emperor Eto Mar 31 '23 at 19:53

1 Answers1

-1

you can try this code

    JArray entriesArr = (JArray)JObject.Parse(json)["entries"];
    foreach (JObject item in entriesArr)
    {
        var prop = item.Properties()
                   .Where(v => v.Value.Type == JTokenType.Object).FirstOrDefault();
        item.AddFirst(new JProperty("uri", prop.Value));
        prop.Remove();
    }

    List<Entry> entries = entriesArr.ToObject<List<Entry>>();

public partial class Entry
{
    public Url Uri { get; set; }

    [JsonProperty("cuid")]
    public string Cuid { get; set; }

    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("description")]
    public string Description { get; set; }

    [JsonProperty("id")]
    public long Id { get; set; }

    [JsonProperty("type")]
    public string Type { get; set; }

    [JsonProperty("ownerid")]
    public long Ownerid { get; set; }

    [JsonProperty("updated")]
    public string Updated { get; set; }

    [JsonProperty("parentid")]
    public long Parentid { get; set; }
}

public partial class Url
{
    [JsonProperty("__deferred")]
    public Deferred Deferred { get; set; }
}

public partial class Deferred
{
    [JsonProperty("uri")]
    public Uri Uri { get; set; }
}
Serge
  • 40,935
  • 4
  • 18
  • 45