OData v4 custom function

I am trying to create a custom function in an OData v4 Web API solution. I need to return the "Orders" collection based on unique logic that cannot be processed by OData. I cannot figure out how to create this custom function without destroying the entire OData service layer. When I decorate the Controller method with the ODataRoute attribute, everything goes to hell. Any basic query generates the same error. Can someone please take a look at the code below and see if you notice something that I am missing?

WebApiConfig.cs

public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); config.MapODataServiceRoute("odata", "odata", model: GetModel()); } public static Microsoft.OData.Edm.IEdmModel GetModel() { ODataModelBuilder builder = new ODataConventionModelBuilder(); builder.EntitySet<Account>("Accounts"); builder.EntitySet<Email>("Emails"); builder.EntitySet<PhoneNumber>("PhoneNumbers"); builder.EntitySet<Account>("Accounts"); builder.EntitySet<Address>("Addresses"); builder.EntitySet<Order>("Orders"); builder.EntitySet<OrderDetail>("OrderDetails"); var orders = builder.EntityType<Order>(); var function = orders.Function("GetByExternalKey"); function.Parameter<long>("key"); function.ReturnsCollectionFromEntitySet<Order>("Orders"); return builder.GetEdmModel(); } } 

OrdersController.cs

 public class OrdersController : ODataController { private SomeContext db = new SomeContext(); ...Other Stuff... [HttpGet] [ODataRoute("GetByExternalKey(key={key})")] public IHttpActionResult GetByExternalKey(long key) { return Ok(from o in db.Orders where //SpecialCrazyStuff is done select o); } } } 

When issuing ANY query at the OData level, I get the following error response.

The GetByExternalKey (key = {key}) path template in the GetByExternalKey action in the Orders controller is not a valid OData path template. Resource not found for segment "GetByExternalKey".

+6
source share
1 answer

In the model builder, the GetByExternalKey function is a related function. According to the OData v4 protocol, a related function is called through a namespace or an alias with a name, so you need to add more to the route attribute:

 [HttpGet] [ODataRoute("Orders({id})/Your.Namespace.GetByExternalKey(key={key})")] public IHttpActionResult GetByExternalKey(long key) { return Ok(from o in db.Orders where//SpecialCrazyStuff is done select o); } 

If you don't know the namespace, just add the GetModel () method below:

 builder.Namespace = typeof(Order).Namespace; 

And replace "Your.Namespace" with a namespace of type "Order".

Here are two examples related to your question, for reference only: https://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v4/ODataFunctionSample/

https://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v4/ODataAttributeRoutingSample/

+3
source

Source: https://habr.com/ru/post/973712/


All Articles