1

Using a normal ApiController in WebApi, I made the following code to define a dynamic map route template for every ApiControllers:

config.Routes.MapHttpRoute(
        name: "Sample",
        routeTemplate: "{sessionId}/{controller}"
     );

I want to achieve a similar behaviour but for every ODataController. I've tried the following code, but it doesn't work:

 config.MapODataServiceRoute(
        routeName: "HSODataRoute",
        routePrefix: "{sessionId}/",
        model: GetEdmModel());

Any idea how this is made in OData? I'm kinda new to it and the internet is lack of information about this.

To be more specific: {sessionId} isn't supposed to be a constant, but a parameter with a Guid value.

João Antunes
  • 798
  • 8
  • 27

3 Answers3

1

The ODataConventionModelBuilder by default maps the route /{controller} to the controller whose name is {controller}Controller. E.g. it automatically routes /Products to ProductsController as long as ProductsController derives from ODataController.

If you want more flexibility, you can additionally use routing attributes. E.g.

[ODataRoutePrefix("Products")]
public class Products : ODataController
Yi Ding - MSFT
  • 2,864
  • 16
  • 16
1

Your following code should work:

config.MapODataServiceRoute(
        routeName: "HSODataRoute",
        routePrefix: "{sessionId}/",
        model: GetEdmModel());

However, you should make sure the request Uri contains only one "/". For example:

I send a Get request as:

http://localhost/{sessionId}/Customers/Default.PrintDate(date=2014-10-24T01:02:03+08:00)

my response is:

{
  "@odata.context":"http://localhost/%7BsessionId%7D/$metadata#Edm.String",
  "value":"10/24/2014 1:02:03 AM +08:00"
}

Where, PrintDate is a custom function bind to collection of customer.

[HttpGet]
public string PrintDate(DateTimeOffset date)
{
    return date.ToString();
}
Sam Xu
  • 3,264
  • 1
  • 12
  • 17
  • The {sessionId} isn't supposed to be a static value. I intend to use the {sessionId} as a Guid parameter. For example: http://localhost/E80DC2C7-3A7E-4E39-8DB1-519EC8E58B4C/Customers/Default.PrintDate(date=2014-10-24T01:02:03+08:00) – João Antunes Jan 08 '15 at 10:15
  • Indeed my code worked :D. I've found the stupid error... I was testing a Apicontroller instead of an ODataController. Thank you for the help! – João Antunes Jan 08 '15 at 12:06
1

After a few tests I've found out that declaring MapODataServiceRoute is not enough! You need also to add MapHttpRoute also, since ODataController derives from ApiController

config.Routes.MapHttpRoute(
    name: "Sample",
    routeTemplate: "{sessionId}/{controller}"
 );

config.MapODataServiceRoute(
    routeName: "HSODataRoute",
    routePrefix: "{sessionId}/",
    model: GetEdmModel());

I discovered this because after I removed MapHttpRoute, I've started to get 404 not found, and when I added MapHttpRoute the resource could be found.

UPDATE:

The final solution that I've come up to solve this issue was posted here: Pass Parameters in OData WebApi Url.

Community
  • 1
  • 1
João Antunes
  • 798
  • 8
  • 27
  • I am trying to do something very similar to this: http://stackoverflow.com/questions/29514873/pass-parameters-in-odata-webapi-url How are you reading out the sessionId? `HttpContext.Current.Request["sessionId"];` returns null for me. – philreed Apr 08 '15 at 16:10
  • After I've lost some time with this I've encountered a solution, not sure if it is the best but it works. I've forgot to update the solution, but I'll do it now. – João Antunes Apr 08 '15 at 20:52