Cashley
Cashley

Reputation: 526

Json.NET Deserialisation - key value pairs?

I'm currently having some trouble deserialising a collection of names key/value pairs using Json.NET

Here's an example of the Json I'm trying to work with:

"prices":
{
    "SharedMinPrice":{"USD":"0.00"},
    "SharedAveragePrice":{"USD":"0.00"},
    "PrivateMinPrice":{"USD":"8.82"},
    "PrivateAveragePrice":{"USD":"26.85"},
    "MinPrice":{"USD":"8.82"},
    "AveragePrice":{"USD":"26.85"}}
}

If I try to deserialise this to a List of a custom type, I get the following error:

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[APITypes.PropertyPrice]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.

I'm using the following code in my backing class:

[JsonProperty("prices")]
    public List<PropertyPrice> Prices { get; set; }

and my PropertyPrice class is:

    internal class PropertyPrice
{

    [JsonProperty("sharedMinPrice")]
    public float sharedMinPrice { get; set; }

    [JsonProperty("sharedAveragePrice")]
    public float sharedAveragePrice { get; set; }

    [JsonProperty("privateMinPrice")]
    public float privateMinPrice { get; set; }

    [JsonProperty("privateAveragePrice")]
    public float privateAveragePrice { get; set; }

    [JsonProperty("minPrice")]
    public float minPrice { get; set; }

    [JsonProperty("averagePrice")]
    public float averagePrice { get; set; }
}

What am I doing wrong?

Thanks in advance for any assistance.

Upvotes: 0

Views: 181

Answers (4)

L.B
L.B

Reputation: 116178

Since it is not an array, you can use Dictionary<string,T> for this. This code works...

var obj = JsonConvert.DeserializeObject<Price>(json);
Console.WriteLine(obj.Prices["SharedMinPrice"]["USD"]);

..

public class Price
{
    public Dictionary<string, Dictionary<string, decimal>> Prices { set; get; }
}

Upvotes: 1

Timothy Shields
Timothy Shields

Reputation: 79601

You are trying to deserialize JSON of the form {"USD": 3.50} into a float. Those types don't match up. Below I define a new type MoneyAmount which does.

internal class MoneyAmount
{
    public float USD { get; set; }
}

internal class PropertyPrice
{

    [JsonProperty("sharedMinPrice")]
    public MoneyAmount sharedMinPrice { get; set; }

    [JsonProperty("sharedAveragePrice")]
    public MoneyAmount sharedAveragePrice { get; set; }

    [JsonProperty("privateMinPrice")]
    public MoneyAmount privateMinPrice { get; set; }

    [JsonProperty("privateAveragePrice")]
    public MoneyAmount privateAveragePrice { get; set; }

    [JsonProperty("minPrice")]
    public MoneyAmount minPrice { get; set; }

    [JsonProperty("averagePrice")]
    public MoneyAmount averagePrice { get; set; }
}

Alternatively, you could use a Dictionary<string, float> in place of MoneyAmount if you want to handle all kinds of currencies dynamically.

Upvotes: 1

Lee Gary
Lee Gary

Reputation: 2397

Your json is not an array type, it should look something like this:

"prices":
{   
    "SharedMinPrice":{"USD":"0.00"},
    "SharedAveragePrice":{"USD":"0.00"},
    "PrivateMinPrice":{"USD":"8.82"},
    "PrivateAveragePrice":{"USD":"26.85"},
    "MinPrice":{"USD":"8.82"},
    "AveragePrice":{"USD":"26.85"}}
}

Upvotes: 0

user2286552
user2286552

Reputation:

Forgot the opening { at the beginning

{"prices": {"SharedMinPrice":{"USD":"0.00"},"SharedAveragePrice":{"USD":"0.00"},"PrivateMinPrice":{"USD":"8.82"},"PrivateAveragePrice":{"USD":"26.85"},"MinPrice":{"USD":"8.82"},"AveragePrice":{"USD":"26.85"}}}

--> use something like http://jsonformatter.curiousconcept.com/ to test your json when it doesn't deserialize

Additionally, you are not passing it in as an array:

{"employees": [{"id":"1"},{"id":"2"}]}

Upvotes: 0

Related Questions