Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ODataConventionModelBuilder with multiple namespaces

Tags:

odata

This is either super straight forward, or its relatively easy to answer. I have the following code in order to set up my OData Routing Conventions:

// OData
var builder = new ODataConventionModelBuilder();

// OData entity sets..
builder.EntitySet<Book>("Books");
builder.EntitySet<Shelf>("Shelves");

// Bound Function..has to be located on the Tables Controller...
builder.Namespace = "BookService";
builder.EntityType<Table>().Collection
    .Function("MostRecent")
    .Returns<DateTimeOffset>();

builder.Namespace = "ShelfService";
builder.EntityType<Shelf>()
    .Action("NearestEmptyShelf");

...But the problem with this is when the application starts, everything is routed against ShelfService rather than the first function being accessible from BookService.MostRecent and ShelfService.NearestEmptyShelf.

I'm sure others have run into this particular problem when creating services (actions/functions) for their OData Controllers. But I'm just after a definitive answer as to whether or not you can have multiple namespaces in the OData Routing Collection?

like image 517
Matthew Merryfull Avatar asked Dec 29 '14 12:12

Matthew Merryfull


Video Answer


1 Answers

You are overwriting your namespace of builder.Namespace = "Bookservice"; with builder.Namespace = "ShelfService";.

To utilize two separate namespaces you need two separate instances of new ODataConventionModelBuilder();

The below is for OData V4

// Book OData Endpoint
var book_builder = new ODataConventionModelBuilder();

// Book OData entity sets..
book_builder.EntitySet<Book>("Books");

// Book Bound Function..has to be located on the Tables Controller...
book_builder.Namespace = "BookService";
book_builder.EntityType<Table>().Collection
    .Function("MostRecent")
    .Returns<DateTimeOffset>();
// Book Config
config.MapODataServiceRoute(
    routeName: "OData - Book",
    routePrefix: "book",
    model: book_builder.GetEdmModel()                
    );

// Shelf OData Endpoint
var shelf_builder = new ODataConventionModelBuilder();

// Shelf OData Entity Sets
shelf_builder.EntitySet<Shelf>("Shelves");

// Shelf Bound Function..has to be located on the Tables Controller...
shelf_builder.Namespace = "ShelfService";
shelf_builder.EntityType<Shelf>()
    .Action("NearestEmptyShelf");
    .Returns<whatever you planned on returning>()
//Shelf Config
config.MapODataServiceRoute(
    routeName: "OData - Shelf",
    routePrefix: "shelf",
    model: shelf_builder.GetEdmModel()                
    );

It has been a while since I've implemented this mechanism, but you may have to overwrite AttributeRoutingConvention to utilize bound functions in multiple namespaces/controllers using the above method. I know I had a hiccup with it at some point and ended up finding a good method on stack overflow for a public class CustomAttributeRoutingConvention : AttributeRoutingConvention that utilized a public static class HttpConfigExt to provide a CustomMapODataServiceRoute to fix the issue.

like image 159
Pynt Avatar answered Jan 04 '23 13:01

Pynt