JurgenW
JurgenW

Reputation: 317

Hierarchical complex type in Web Api ODATA Controller

I have the following complex type to return from an Web Api ODATA controller:

public class TreeItem
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public List<TreeItem> Children { get; set; }
    }

This is the controller method:

// GET: odata/TreeItems
public IHttpActionResult GetTreeItems(ODataQueryOptions<TreeItem> queryOptions)
        {
            // validate the query.
            try
            {
                queryOptions.Validate(_validationSettings);
            }
            catch (ODataException ex)
            {
                return BadRequest(ex.Message);
            }

            var treeItems = new List<TreeItem>();
            treeItems.Add(new TreeItem() { Id = 1, Name = "Geleiding", Children = new List<TreeItem>() { new TreeItem(){ Id=4, Name="Item1-1", Children=new List<TreeItem>()} } });
            treeItems.Add(new TreeItem() { Id = 2, Name = "Item 2", Children = new List<TreeItem>() });
            treeItems.Add(new TreeItem() { Id = 3, Name = "Item 3", Children = new List<TreeItem>() });
            return Ok<IEnumerable<TreeItem>>(treeItems);
        }

In WebApiCOnfig: builder.EntitySet("TreeItems").EntityType.ComplexProperty(c => c.Children);

When I go to this URL: http://localhost:50997/odata/TreeItems

I get this response:

{
  "odata.metadata":"http://localhost:50997/odata/$metadata#TreeItems","value":[
    {
      "Children":{
        "Capacity":4
      },"Id":1,"Name":"Geleiding"
    },{
      "Children":{
        "Capacity":0
      },"Id":2,"Name":"Item 2"
    },{
      "Children":{
        "Capacity":0
      },"Id":3,"Name":"Item 3"
    }
  ]
}

How do I get the Children list to show completely including all levels it may have?

$expand=Children does not work, says Children is not a navigational property.

Thanks for you help!

Upvotes: 4

Views: 2071

Answers (1)

Sam Xu
Sam Xu

Reputation: 3380

Remove ODataQueryOptions<TreeItem> queryOptions from the action, add the [EnableQuery] on the action.

[EnableQuery]
public IHttpActionResult GetTreeItems()
{
 ...
}

Thanks.

Besides, your title is not correct. TreeItem is built as entity type by you, not complex type. Entity type and complex type are both structural type, but entity type must have key, while complex type needn't.

===============Iteration 2 ===============

  1. As I said, you can't explicitly mapping the Children as complex type. So,

the following code is unnecessary:

builder.EntitySet("TreeItems").EntityType.ComplexProperty(c => c.Children); 

If you are using ODataConventionModelBuilder, just remove the .ComplexProperty() function call.

  1. You can use $levels to expand sub levels of Children. I build a sample project that you can refer to, in which I give four queries:

    http://localhost/odata/TreeItems

    http://localhost/odata/TreeItems?$expand=Children

    http://localhost/odata/TreeItems?$expand=Children($levels=2)

    http://localhost/odata/TreeItems?$expand=Children($levels=max)

All queries will return different results (I made some changes in the controller). You can easily run this console application to check the result. I do think you can find what you want.

Please let me know if you have any concern about the project.

Upvotes: 2

Related Questions