0

I have JSON like this

    {
    "rates": {
        "2018-05-04": {
            "USD": 0.2813388807,
            "GBP": 0.2074019228
        },
        "2018-08-27": {
            "USD": 0.2723718099,
            "GBP": 0.2115780848
        }
        ...etc etc
    },
    "start_at": "2018-01-01",
    "base": "PLN",
    "end_at": "2018-09-01"
    }

I want to map it to C# object. I tried to use json@csharp, but it gives me something like this

public class __invalid_type__20180504
{
    public double USD { get; set; }
    public double GBP { get; set; }
}

public class __invalid_type__20180827
{
    public double USD { get; set; }
    public double GBP { get; set; }
}

public class Rates
{
    public __invalid_type__20180504 __invalid_name__2018-05-04 { get; set; }
    public __invalid_type__20180827 __invalid_name__2018-08-27 { get; set; }
}

public class RootObject
{
    public Rates rates { get; set; }
    public string start_at { get; set; }
    public string @base { get; set; }
    public string end_at { get; set; }
}

I do not want to have class names like "__invalid_type__xxxxxxxx", and I am looking for a way to map it to one class so that I have list of one class type. I am using DataContractJsonSerializer and System.Net.Http.HttpClient

stefam mierz
  • 53
  • 1
  • 6
  • the json is not valid - you need a property name for the date(s) – jazb Nov 25 '19 at 07:12
  • because it does not know what "2018-05-04" and "2018-08-27" are, just adjust your class rate yo list of the subclass (which contains USD and GBP values) – styx Nov 25 '19 at 07:12
  • @Jazb I've got json from here [link](https://api.exchangeratesapi.io/history?start_at=2018-01-01&end_at=2018-09-01&base=PLN&symbols=USD,GBP) – stefam mierz Nov 25 '19 at 07:24
  • @stefammierz please check my answer. – Jonathan Alfaro Nov 25 '19 at 07:24
  • the link is giving non-valid json – jazb Nov 25 '19 at 07:26
  • Does this answer your question? [How can I deserialize JSON to a simple Dictionary in ASP.NET?](https://stackoverflow.com/questions/1207731/how-can-i-deserialize-json-to-a-simple-dictionarystring-string-in-asp-net) – xdtTransform Nov 25 '19 at 07:58
  • @Jazb, the Json is totaly valid under the [spec](http://www.json.org). Dictionary have unique key, and Array representation won't ensure uniqueness, Dict Key are mapped to Property Name and and Dict Value to Property Value. Every time you see something that look like an array but it's missing the `[]` or have "_property name as value_", it might be a `Dictionary`. like `{ "key1": "value1", "key2": "value2"}` – xdtTransform Nov 25 '19 at 08:05

3 Answers3

2

You don't actually need to use a tool for generating classes for the json mentioned above. You can have a root object like this.

public class RootObject
{
    public Dictionary<string,Rate> rates { get; set; }
    public string start_at { get; set; }
    public string @base { get; set; }
    public string end_at { get; set; }
}

And since your property names are same for the rates you can use this for defining rate object.

public class Rate
{
    public double USD { get; set; }
    public double GBP { get; set; }
}

Since @stefammierz mentioned in the comment that he is using DataContractJsonSerializer, a trick is needed in order to make it work to deserialize to dictionary like below :

var settings = new DataContractJsonSerializerSettings {UseSimpleDictionaryFormat = true};
var serializer = new DataContractJsonSerializer(typeof(RootObject),settings);
Eldar
  • 9,781
  • 2
  • 10
  • 35
0

When a JSON field name is dynamic, I.E the dates

you can use JsonExtensionData and yor data will have resulted as key:value pairs

So your classes look like these

        public class RootObject
        {
            public Rates rates { get; set; }
            public string start_at { get; set; }
            public string @base { get; set; }
            public string end_at { get; set; }
        }

        public class Rates
        {
            [JsonExtensionData]
            public Dictionary<string, JToken> Fields { get; set; }
        }

Example Output

Key: 2018-05-04

Value - { "USD": 0.2813388807, "GBP": 0.2074019228 }

enter image description here

styx
  • 1,852
  • 1
  • 11
  • 22
0

You can Just paste your Json here and create the class and Use NewtonsoftJson to parse,

public class RootObject
{
    [JsonProperty("rates")]
    public Dictionary<string, Dictionary<string, double>> Rates { get; set; }

    [JsonProperty("start_at")]
    public DateTimeOffset StartAt { get; set; }

    [JsonProperty("base")]
    public string Base { get; set; }

    [JsonProperty("end_at")]
    public DateTimeOffset EndAt { get; set; }
}

This is the best and quickest way I have seen so far.

Sushant Yelpale
  • 860
  • 6
  • 19