0

I'm trying to create a basic Xamarin Forms app that can list available gateways on my PFsense firewall, Show the available gateway and change this to another gateway to route through if required. The problem I have is I cannot deserialize the JSON in C# because each object has a different object name:

    {
    "status": "ok",
    "code": 200,
    "return": 0,
    "message": "Success",
    "data": {
        "GW_WAN_1": {
            "interface": "hn0",
            "gateway": "192.168.0.1",
            "name": "GW_WAN_1",
            "weight": "1",
            "ipprotocol": "inet",
            "interval": "500",
            "time_period": "60000",
            "alert_interval": "1000",
            "descr": "Interface wan Gateway",
            "data_payload": "1",
            "latencylow": "200",
            "latencyhigh": "500",
            "losslow": "10",
            "losshigh": "20",
            "loss_interval": "2000",
            "monitor": "192.168.0.1",
            "friendlyiface": "wan",
            "friendlyifdescr": "RED",
            "isdefaultgw": true,
            "attribute": 0,
            "tiername": "Default (IPv4)"
        },
        "INT1_DHCP6": {
            "dynamic": true,
            "ipprotocol": "inet6",
            "gateway": "fe80::1af1:45ff:fe90:4b13",
            "interface": "hn0",
            "friendlyiface": "wan",
            "friendlyifdescr": "RED",
            "name": "INT1_DHCP6",
            "attribute": "system",
            "isdefaultgw": true,
            "monitor": "fe80::1af1:45ff:fe90:4b13",
            "descr": "Interface RED_DHCP6 Gateway",
            "tiername": ""
        },
        "VPN_EUR_1": {
            "interface": "ovpns1",
            "gateway": "192.168.1.2",
            "name": "VPN_EUR_1",
            "weight": "1",
            "ipprotocol": "inet",
            "interval": "500",
            "time_period": "60000",
            "alert_interval": "1000",
            "descr": "Interface VPN_EUR_1 Gateway",
            "data_payload": "1",
            "latencylow": "200",
            "latencyhigh": "500",
            "losslow": "10",
            "losshigh": "20",
            "loss_interval": "2000",
            "dynamic": true,
            "monitor": "192.168.1.2",
            "friendlyiface": "opt4",
            "friendlyifdescr": "VPN_EUR_1",
            "attribute": 1,
            "tiername": ""
        },
        "Null4": {
            "name": "Null4",
            "interface": "lo0",
            "ipprotocol": "inet",
            "gateway": "127.0.0.1",
            "attribute": "system",
            "tiername": ""
        },
        "Null6": {
            "name": "Null6",
            "interface": "lo0",
            "ipprotocol": "inet6",
            "gateway": "::1",
            "attribute": "system",
            "tiername": ""
        },
        "VPN_EUR_1V6": {
            "dynamic": false,
            "ipprotocol": "inet6",
            "gateway": null,
            "interface": "ovpns1",
            "friendlyiface": "opt4",
            "friendlyifdescr": "VPN_EUR_1",
            "name": "VPN_EUR_1V6",
            "attribute": "system",
            "descr": "Interface VPN_EUR_1V6 Gateway",
            "tiername": ""
        }
    }
}

Here's how I've gone about trying to deserialize:

string authHeader = Constants.AUTH_HEADER;
                client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", authHeader);
                var response = await client.GetAsync(Constants.GATEWAY);

                var json = await response.Content.ReadAsStringAsync();
                var gateways = JsonConvert.DeserializeObject<Data>(json);

The C# Object (Generated using json to C# converter):

public class GW_WAN_1
{
    public string @interface { get; set; }
    public string gateway { get; set; }
    public string name { get; set; }
    public string weight { get; set; }
    public string ipprotocol { get; set; }
    public string interval { get; set; }
    public string time_period { get; set; }
    public string alert_interval { get; set; }
    public string descr { get; set; }
    public string data_payload { get; set; }
    public string latencylow { get; set; }
    public string latencyhigh { get; set; }
    public string losslow { get; set; }
    public string losshigh { get; set; }
    public string loss_interval { get; set; }
    public string monitor { get; set; }
    public string friendlyiface { get; set; }
    public string friendlyifdescr { get; set; }
    public bool isdefaultgw { get; set; }
    public int attribute { get; set; }
    public string tiername { get; set; }
}

public class INT1_DHCP6
{
    public bool dynamic { get; set; }
    public string ipprotocol { get; set; }
    public string gateway { get; set; }
    public string @interface { get; set; }
    public string friendlyiface { get; set; }
    public string friendlyifdescr { get; set; }
    public string name { get; set; }
    public string attribute { get; set; }
    public bool isdefaultgw { get; set; }
    public string monitor { get; set; }
    public string descr { get; set; }
    public string tiername { get; set; }
}

public class VPN_EUR_1
{
    public string @interface { get; set; }
    public string gateway { get; set; }
    public string name { get; set; }
    public string weight { get; set; }
    public string ipprotocol { get; set; }
    public string interval { get; set; }
    public string time_period { get; set; }
    public string alert_interval { get; set; }
    public string descr { get; set; }
    public string data_payload { get; set; }
    public string latencylow { get; set; }
    public string latencyhigh { get; set; }
    public string losslow { get; set; }
    public string losshigh { get; set; }
    public string loss_interval { get; set; }
    public bool dynamic { get; set; }
    public string monitor { get; set; }
    public string friendlyiface { get; set; }
    public string friendlyifdescr { get; set; }
    public int attribute { get; set; }
    public string tiername { get; set; }
}

public class Null4
{
    public string name { get; set; }
    public string @interface { get; set; }
    public string ipprotocol { get; set; }
    public string gateway { get; set; }
    public string attribute { get; set; }
    public string tiername { get; set; }
}

public class Null6
{
    public string name { get; set; }
    public string @interface { get; set; }
    public string ipprotocol { get; set; }
    public string gateway { get; set; }
    public string attribute { get; set; }
    public string tiername { get; set; }
}

public class VPN_EUR_1V6
{
    public bool dynamic { get; set; }
    public string ipprotocol { get; set; }
    public object gateway { get; set; }
    public string @interface { get; set; }
    public string friendlyiface { get; set; }
    public string friendlyifdescr { get; set; }
    public string name { get; set; }
    public string attribute { get; set; }
    public string descr { get; set; }
    public string tiername { get; set; }
}

public class Data
{
    public GW_WAN_1 GW_WAN { get; set; }
    public INT1_DHCP6 INT1_DHCP6 { get; set; }
    public VPN_EUR_1 VPN_EUR_1 { get; set; }
    public Null4 Null4 { get; set; }
    public Null6 Null6 { get; set; }
    public VPN_EUR_1V6 VPN_NL_VPNV6 { get; set; }
}

public class Root
{
    public string status { get; set; }
    public int code { get; set; }
    public int @return { get; set; }
    public string message { get; set; }
    public Data data { get; set; }
}

The problem is in the gateways variable, all of the properties are null. I think because of how the JSON is structured in the response, it might not be possible in C#, but perhaps there's another way of going about it?

The API for the firewall is here: https://github.com/jaredhendrickson13/pfsense-api

Thanks

  • `public Dictionary data { get; set; }` and define a single type with all the possible fields? Then define `gateway` as a string, or write your own `IPAddress` serialiser. – Jeremy Lakeman Sep 27 '21 at 05:24
  • this might be what you need https://stackoverflow.com/questions/32085317/how-to-get-the-name-of-a-json-object-using-c-newtonsoft-json – codebrane Sep 27 '21 at 07:08

0 Answers0