1
votes

I'm trying to get my Odata enpoint to have an action that returns the same DataType as the controller it's on.

I tried the following in my WebApiConfig:

var entity = builder.EntitySet<Entity>("entities");
             builder.Entity<Entity>().Action("UnassignedMarkets").ReturnsCollection<Entity>();

I'm getting the following error

An exception of type 'System.InvalidOperationException' occurred in System.Web.Http.OData.dll but was not handled in user code Additional information: The EDM type 'MyProj.DataAccess.Views.Entity' is already declared as an entity type. Use the method 'ReturnsCollectionFromEntitySet' if the return type is an entity collection.

So I change my code to the following and it compiles

var entity = builder.EntitySet<Entity>("entities");
             builder.Entity<Entity>().Action("UnassignedMarkets").ReturnsCollectionFromEntitySet<Entity>("entities");

I browse to the action using fiddler

http://localhost:777/odata/entities/UnassignedMarkets

which returns:

{ "message": "The OData path is invalid.", "exceptionMessage": "Invalid action detected. 'UnassignedMarkets' is not an action that can bind to 'Collection([MyProj.DataAccess.Dtos.Views.Entity Nullable=False])'.", "exceptionType": "Microsoft.Data.OData.ODataException", "stackTrace": " at System.Web.Http.OData.Routing.DefaultODataPathHandler.ParseAtEntityCollection(IEdmModel model, ODataPathSegment previous, IEdmType previousEdmType, String segment)\r\n at System.Web.Http.OData.Routing.DefaultODataPathHandler.ParseAtCollection(IEdmModel model, ODataPathSegment previous, IEdmType previousEdmType, String segment)\r\n at System.Web.Http.OData.Routing.DefaultODataPathHandler.ParseNextSegment(IEdmModel model, ODataPathSegment previous, IEdmType previousEdmType, String segment)\r\n at System.Web.Http.OData.Routing.DefaultODataPathHandler.Parse(IEdmModel model, String odataPath)\r\n at System.Web.Http.OData.Routing.ODataPathRouteConstraint.Match(HttpRequestMessage request, IHttpRoute route, String parameterName, IDictionary`2 values, HttpRouteDirection routeDirection)" }

public class EntitiesController : ODataController
{
     private readonly Storage _storage;

     public EntitiesController(Storage storage)
     {
            _storage = storage;
     }

     [Queryable]
     public IQueryable<Entity> Get()
     {
        return _storage.Entities;
     }


     [HttpPost]
     public IQueryable<Entity> UnassignedMarkets(ODataQueryOptions<Entity> queryOptions)
     {
         return buildEntities();
     }
}
1

1 Answers

1
votes

According to your request:

http://localhost:777/odata/entities/UnassignedMarkets

the action "UnassignedMarkets" is bound to collection of entity.

So you can try the code below to build your model:

var entity = builder.EntitySet<Entity>("entities");
builder.Entity<Entity>().Collection.Action("UnassignedMarkets").ReturnsCollectionFromEntitySet<Entity>("entities");