I am using WebApi v5 and OData v4.
I have a controller which extends from ApiController with a method that polls a repository for a simple list of Categories.
public class ITSRController : ApiController
{
private IITSRRepository repository;
public ITSRController(IITSRRepository itsrRepository)
{
repository = itsrRepository;
}
[Route("v1/request/categories")]
[HttpGet]
public IQueryable<Category> Categories()
{
return repository.Categories.AsQueryable();
}
The Category class is a simple repository Entity class:
public class Category
{
public int Id { get; set; }
public string CategoryName { get; set; }
}
My WebApiConfig has the following code in it:
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.AddODataQueryFilter();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "itsrapi/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
Without any additional code, I get the expected results for GET requests like:
v1/request/categories/?$orderby=CategoryName
v1/request/categories/?$filter=CategoryName eq 'Cat1' or CategoryName eq 'Cat2'
v1/request/categories/?$top=4&$orderby=Id&$skip=4
When I make the following GET request: v1/request/categories/?$select=CategoryName
I get the following exception:
Object of type 'System.Linq.EnumerableQuery
1[System.Web.Http.OData.Query.Expressions.SelectExpandBinder+SelectSome
1[SWF.ITSR.Domain.Entities.Category]]' cannot be converted to type 'System.Collections.Generic.IEnumerable`1[SWF.ITSR.Domain.Entities.Category]'.
After some research I changed my Categories method in my controller:
[Route("v1/request/categories")]
[HttpGet]
[EnableQuery]
public IQueryable<Category> Categories(ODataQueryOptions options)
{
if (options.SelectExpand != null)
{
Request.ODataProperties().SelectExpandClause = options.SelectExpand.SelectExpandClause;
}
return repository.Categories.AsQueryable();
}
When I call $select after this change I get the same error as above.
I've tried modifying the method to the following:
public IEnumerable<Category> Categories(ODataQueryOptions options)
{
...
return repository.Categories.ToList();
}
and I get a slightly different exception when calling $select
Unable to cast object of type 'System.Linq.EnumerableQuery
1[System.Web.Http.OData.Query.Expressions.SelectExpandBinder+SelectSome
1[SWF.ITSR.Domain.Entities.Category]]' to type 'System.Collections.Generic.IEnumerable`1[SWF.ITSR.Domain.Entities.Category]'.
which may be semantically the same as the first error (perhaps failing somewhere else)
I spent a good many hours researching how to add $select (and $expand) functionality to my WebApi controller to no avail. I have tried countless posted suggestions, and still the answer eludes me. I would appreciate any help.
Thanks,
Ken
Is there a reason for you to use both Web API and Web API OData? If not, I suggest you Controller inherits directly from ODataController. Then you don't to specify anything particular to make $select work. An example is https://github.com/OData/ODataSamples/tree/master/SampleService