0

I feel like I'm making this much harder than it needs to be.

In C# using Netwonsoft JSON Compact with external data. Trying to figure out how to deserialize/parse data that looks like

{"http":{"0":{"title":"arbitrary","value":"arbitrary"},"1":{"title":"arbitrary","value":"arbitrary"}},"sip":{"1003":{"title":"arbitrary","value":"none"}}}

It's essentially an array of notifications and the ID -- "0", "1", and "1003" in the above examples is an arbitrary value and appears to have a valid range of 0 and roughly 65535.

But it's not formatted as an array (or I wouldn't be here) -- need help figuring out how to deserialize the value object while essentially ignoring the string identifier.

Thanks in advance

2
  • You won't be able to use Newtonsoft to automate that because it deserializes JSON objects as they are written. In this case, you're trying to imply that each numerical key be treated as an array index, so you'll have to walk the object the hard way. Commented Apr 5, 2018 at 16:08
  • That's where I was going but was hoping I had missed something before I started brute forcing things. Thanks for confirming I wasn't missing something stupid at least. Commented Apr 5, 2018 at 16:10

2 Answers 2

1

You can't easily deserialize it as an array, but you can deserialize it to a dictionary with integer keys. I don't know about Json.NET Compact, but this works fine with regular Json.NET:

using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;

class Root
{
    public Dictionary<int, Property> Http { get; set; }
    public Dictionary<int, Property> Sip { get; set; }
}

class Property
{
    public string Title { get; set; }
    public string Value { get; set; }
}

class Test
{
    static void Main()
    {
        string json = File.ReadAllText("test.json");
        var root = JsonConvert.DeserializeObject<Root>(json);
        foreach (var entry in root.Http)
        {
            Console.WriteLine($"{entry.Key}: {entry.Value.Title}/{entry.Value.Value}");
        }
    }
}

If you really need the properties as arrays, I'd suggest having two separate classes: one for the JSON representation, and then another for real usage. For example:

class RootJson
{
    public Dictionary<int, Property> Http { get; set; }
    public Dictionary<int, Property> Sip { get; set; }
}

class Root
{
    // TODO: Control access more :)
    public Property[] Http { get; set; }
    public Property[] Sip { get; set; }
}

Then:

var rootJson = ...;
var root = new Root
{
    Http = rootJson.Http.Values.ToArray(),
    Sip = rootJson.Sip.Values.ToArray(),
};
Sign up to request clarification or add additional context in comments.

2 Comments

Holy cow... thanks and so easy to implement -- does exactly what I need! Amazing how when tunnel vision kicks in you can get stuck going down track even there's a shorter path.
@LincolnKing-Cliby: Or another way to look at it is that Json.NET is really flexible :)
0

If you can't change the structure of the JSON, you can always do something like this. The dynamic type figures out what to do on runtime.

dynamic d = JsonConvert.DeserializeObject("{'http':{'0':{'title':'arbitrary','value':'arbitrary'},'1':{'title':'arbitrary','value':'arbitrary'}},'sip':{'1003':{'title':'arbitrary','value':'none'}}}");

Console.WriteLine(d.http["0"].title); // arbitrary

foreach(var prop in d.http) {
  Console.WriteLine(prop);   
}

foreach(var prop in d.sip) {
  Console.WriteLine(prop);   
}

Final output:

arbitrary
"0": {
  "title": "arbitrary",
  "value": "arbitrary"
}
"1": {
  "title": "arbitrary",
  "value": "arbitrary"
}
"1003": {
  "title": "arbitrary",
  "value": "none"
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.