0

I am making a WebAPI call to get an object back similar to this one:

public class DocumentCategoryModel : IDocumentCategoryTree
    {
        public DocumentCategoryModel()
        {
            SubCategories = new List<IDocumentCategoryTree>();
        }

        public int ID { get; set; }
        public ICollection<IDocumentCategoryTree> SubCategories { get; set; }
    }

The ID and other properties are populated correctly. The SubCategories prop has a collection of the correct size, but every entry is null.

Any idea why? I can't make it a collection of a concrete type (out of my control), but the WebAPI is able to figure out which class it should be...

  • How do you expect WebAPI to know which type of object to create to put into the `SubCategories` collection? – StriplingWarrior Apr 08 '16 at 18:39
  • 2
    I don't understand this statement: `I can't make it a collection of a concrete type (out of my control), but the WebAPI is able to figure out which class it should be...` I think this **is** your problem, the JSON deserializer can't deserialize to interfaces and unless you're telling it how, it can't just search all your types to try to figure out which concrete class to instantiate. – CodingGorilla Apr 08 '16 at 18:39
  • @CodingGorilla How do I go about telling it how to deserialize? – Garrett Daniel DeMeyer Apr 08 '16 at 18:41

2 Answers2

1

This answer assumes you're using JSON.net which is the default with ASP.NET WebAPI. Since JSON.net doesn't understand how to create a concrete instance of IDocumentCategoryTree it cannot deserialize that automatically for you. So you will need to do this youself, the way I would do this is using a JsonConverter for your class:

public class DocumentCategoryModel : IDocumentCategoryTree
{
    public DocumentCategoryModel()
    {
        SubCategories = new List<IDocumentCategoryTree>();
    }

    public int ID { get; set; }

    [JsonConverter(typeof(DocumentCategoryTreeConverter)]
    public ICollection<IDocumentCategoryTree> SubCategories { get; set; }
}

public class DocumentCategoryTreeConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        // Todo if desired
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        return serializer.Deserialize<TestTree>(reader);
    }

    public override bool CanConvert(Type objectType)
    {
        // Todo
    }
}

This is a very simplistic and incomplete example to give you an idea how you can do this and get you started. You can read more about JsonConverters in some other SO posts starting here: How to implement custom JsonConverter in JSON.NET to deserialize a List of base class objects?.

Community
  • 1
  • 1
CodingGorilla
  • 19,612
  • 4
  • 45
  • 65
  • I ended up doing something similar. I used JsConfig.RawDeserializeFn = (value) => {return JsonSerializer.DeserializeFromString(value);}; However, when I get a couple levels deep, the values are null again... – Garrett Daniel DeMeyer Apr 12 '16 at 13:33
0

XML and JSON serialization/deserializtion should be happening with concrete classes. If it doesn't have a concrete it won't know how to properly serialize it. I suggest creating a concrete for IDocumentCategoryTree, something like DocumentCatTreeApiModel. That will allow for the serialization process to work properly.

jhilden
  • 12,207
  • 5
  • 53
  • 76