I'm using the ASP.Net WebAPI nightly build (2013-01-16) to get the latest OData support possible.
As the Meta-Me blog on MSDN OData 0.2.0-alpha release post says, there's now an EntitySetController<T>
from which OData controllers can be derived to take away a lot of the pain and plumbing code.
The EntitySetController<T>
class implements Get() as
[Queryable]
public virtual IQueryable<TEntity> Get()
{
throw EntitySetControllerHelpers.GetNotImplementedResponse(Request);
}
I'd like to make use of the more specific Get(ODataQueryOptions options)
method offered by the ASP.Net Web API OData support.
I've coded it as
public IEnumerable<Patient> Get(ODataQueryOptions options)
{
IQueryable patients = entities.Patients;
if (options.Filter != null)
{
patients = options.Filter.ApplyTo(patients, new ODataQuerySettings());
}
return (patients as IQueryable<Patient>).AsEnumerable();
}
(I've also had this return IQueryable<> and saw someone else talk about an ODataResult - that's a type I can't discover at the moment).
However, if I try to use the ODataQueryOptions-based Get method in my own controller I get an error message about multiple actions matching the request. Specifically that error is
Multiple actions were found that match the request:
System.Collections.Generic.IEnumerable`1[Dox.Server.Model.Patient] Get(System.Web.Http.OData.Query.ODataQueryOptions) on type Dox.Server.Web.Controllers.PatientController
System.Linq.IQueryable`1[Dox.Server.Model.Patient] Get() on type System.Web.Http.OData.EntitySetController`2[[Dox.Server.Model.Patient, Dox.Server.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Guid, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
I assume this is due to the route resolver (sorry if that's poor ASP.NET routing terminology) seeing Get() or Get(...) on the controller's base class as well as the controller class itself.
Questions:
a) Is there some way of adjusting routes to fix this?
b) If not, should I make my own version of EntitySetController<T>
and swap out it's Get() method?
The configuration being called by Application_Start() is limited to
public static void EnableOData( HttpConfiguration config )
{
var model = BuildModelImplicitly(config);
//As per LinqPad forum: http://forum.linqpad.net/discussion/178/odata-v3-not-working
IEdmEntityContainer container = model.EntityContainers().First();
model.SetIsDefaultEntityContainer(container, true);
//config.EnableOData(model, "api");
config.Routes.MapODataRoute("OData", "api", model);
//config.EnableSystemDiagnosticsTracing();
}
There's no other configuration being called to do with routes or handlers, etc. Note that the EnableOData() method on HttpConfiguration no longer exists in the latest nightly builds as per this CodePlex discussion.
Thanks very much!
It's very cool to see that you're using our nightly builds :)
The reason you're getting a multiple matching actions error is because EntitySetController already defines a Get method. The good news is that EntitySetController also defines a QueryOptions
property that you can use to retrieve the query options. So you should be able to override the EntitySetController's Get method and use the query options property instead of the parameter. It should behave exactly the same way as if you had bound the query options to an action parameter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With