Reputation: 26971
This first GET works perfectly fine:
http://localhost/webservice/odata/MyStuff?$filter=Id eq 2&$expand=History
It returns an array of MyStuff
and History
is expanded.
However, if I try to get MyStuff with the key specified, History navigation property is not expanded.
http://localhost/webservice/odata/MyStuff(2)?$expand=History
I already have the HttpConfiguration
configured as follows at startup
HttpConfiguration
.Filter()
.Expand()
.Select()
.OrderBy()
.MaxTop(null)
.Count();
Upvotes: 2
Views: 1263
Reputation: 16554
There are multiple angles to problems like this:
EnableQueryAttribute
configurationYou've already demonstrated that the data exists, so we can discount the data itself but the remaining factors can be implemented in all sorts of combinations.
You should update your question to show an example of your controller method that handles the GET by Key request
If you are using an ORM like Entity Framework then the following simple controller shows a minimal implementation that should work:
[OData.EnableQuery]
public virtual IHttpActionResult Get([FromODataUri] TKey key, ODataQueryOptions<MyStuff> queryOptions)
{
return SingleResultAction(dbContext.MyStuff.Where(x => x.Id == 2));
}
There are of course many other ways, from a minimal standpoint, using SingleResultAction
forces you to pass in a query and validates that it only returns a single result.
As long as an IQueryable<>
result is returned from your method, the EnableQueryAttribute
will try to apply the queryOptions
to your query automatically.
If your result set is manually constructed, or is NOT returned as IQueryable<>
or cannot be automatically chained then you will have to Apply the $expand
query option manually.
You might do this to allow only expansion on certain navigation properties, this next example prepares an item by aggressively loading all the History
records into memory
Not recommended, especially if your navigation property may have many rows and the user will not be expanding very frequently, but it works:
[OData.EnableQuery]
public virtual MyStuff Get([FromODataUri] TKey key, ODataQueryOptions<MyStuff> queryOptions)
{
var item = dbContext.MyStuff.Include(X => x.History).Single(x => x.Id == 2);
return item;
}
This example will still allow EnableQueryAttribute
to $expand
and even to $sort
and $filter
the records in the expansion, however, because the entire available data has been loaded into memory, there is no way for the EnableQueryAttribute
to load additional endpoints.
in this last example, even though the
History
items were loaded into memory, the will only appear in the JSON response if the$expand=History
query option is provided by the caller.
There are many other scenarios, OP didn't provide their implementation code so its a ll speculative from here. I have deliberately NOT demonstrated how to manually Apply the QueryOptions to your data query, which you can do, but until you get the hang of it, I encourage you to stay closer to a minimal implementation, we get a lot OOTB with OData, usually enough to get by.
Upvotes: 1