1

I have a following JSON string:

{
    "items" : "1",
    "itemdetails": 
    [
        {
            "id" : "5",
            "name:" "something"
        }
    ]
}

items represents item count and actual items are in itemdetails.

I would like to deserialize this to a class like this:

class Parent
{
    JsonProperty("itemdetails")]
    public IEnumerable<Item> Items { get; set; }
}

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

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

However, when I call

JsonConvert.DeserializeObject<Parent>(inputString)

I get a JsonSerializationException that string "1" cannot be converted to IEnumerable<Item>. I guess the parser is trying to deserialize items from JSON into Items property because they match by name. And it's ignoring the JsonProperty attribute.

Is this by design? Any workarounds? Thanks!

EDIT

As Brian Rogers commented, this code as it is works correctly. I figured that I missed to add a piece of the puzzle.

The problem is if I want to use private collection setters and initialize those properties from the constructor.

public Parent(IEnumerable<Item> items)
{
    this.Items = items;
}

This is causing the exception to be thrown. What should I do here? Annotate constructor arguments somehow? Or use ConstructorHandling.AllowNonPublicDefaultConstructor?

3
  • I deleted my answer since you stated the reason in the question. give the parser a place to store items to. Commented Jul 22, 2014 at 13:20
  • @Johannes: I don't need that property, I would like to skip it when parsing. Is there no other way? Commented Jul 22, 2014 at 13:37
  • @lukeguy It's fine. If a property is not defined in your class, it will be skipped by default. Commented Jul 22, 2014 at 13:42

1 Answer 1

3

I see two issues. First, your JsonProperty attribute is malformed.

You have:

JsonProperty("itemdetails"]

It should be:

[JsonProperty("itemdetails")]

Secondly, part of your JSON is invalid.

You have this:

 "name:" "something",

It should be:

 "name" : "something"

After fixing both of those problems, it worked just fine for me. Here is the test program I used:

class Program
{
    static void Main(string[] args)
    {
        string json = @"
        {
            ""items"" : ""1"",
            ""itemdetails"": 
            [
                {
                    ""id"" : ""5"",
                    ""name"" : ""something""
                }
            ]
        }";

        Parent parent = JsonConvert.DeserializeObject<Parent>(json);
        foreach (Item item in parent.Items)
        {
            Console.WriteLine(item.Name + " (" + item.Id + ")");
        }
    }
}

class Parent
{
    [JsonProperty("itemdetails")]
    public IEnumerable<Item> Items { get; set; }
}

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

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

Output:

something (5)

EDIT

OK, so if I understand you correctly, your real Parent class actually looks like this:

class Parent
{
    public Parent(IEnumerable<Item> items)
    {
        this.Items = items;
    }

    [JsonProperty("itemdetails")]
    public IEnumerable<Item> Items { get; private set; }
}

In this case you have a couple of choices to get it to work:

You either can change the name of the parameter in your constructor to match the JSON, e.g.:

    public Parent(IEnumerable<Item> itemdetails)
    {
        this.Items = itemdetails;
    }

OR you can add a separate private constructor for Json.Net to use:

class Parent
{
    public Parent(IEnumerable<Item> items)
    {
        this.Items = items;
    }

    [JsonConstructor]
    private Parent()
    {
    }

    [JsonProperty("itemdetails")]
    public IEnumerable<Item> Items { get; private set; }
}
Sign up to request clarification or add additional context in comments.

4 Comments

I was typing an example out of my head directly in the browser, that's why I have typos. I'll fix them.
The fact remains that it works if you have your attributes correct (and the JSON is correct). So I would check your code to make sure that you have not made a typo in the JsonProperty attribute on your "Items" property.
Thanks for noticing the typos. I added an edit, parametrized constructor is the problem.
@lukeguy I've updated my answer to address your edit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.