如何将参数声明为 OData 的前缀

How to declare a parameter as prefix on OData

在WebApi中使用一个普通的ApiController,我编写了以下代码来为每个ApiControllers定义一个动态地图路由模板:

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

我想为每个 ODataController 实现类似的行为。 我尝试了以下代码,但它不起作用:

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

知道这是如何在 OData 中制作的吗?我对它有点陌生,互联网上缺乏这方面的信息。

更具体地说:{sessionId} 不应是常量,而是具有 Guid 值的参数。

ODataConventionModelBuilder 默认将路由 /{controller} 映射到名称为 {controller}Controller 的控制器。例如。只要 ProductsController 来自 ODataController.

,它就会自动将 /Products 路由到 ProductsController

如果你想要更多的灵活性,你可以额外使用路由属性。例如

[ODataRoutePrefix("Products")]
public class Products : ODataController

您的以下代码应该有效:

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

但是,您应该确保请求 Uri 包含 只有一个“/”。 例如:

我发送 Get 请求为:

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

我的回复是:

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

其中,PrintDate 是绑定到客户集合的自定义函数。

[HttpGet]
public string PrintDate(DateTimeOffset date)
{
    return date.ToString();
}

经过几次测试,我发现仅仅声明 MapODataServiceRoute 是不够的! 您还需要添加 MapHttpRoute,因为 ODataController 派生自 ApiController

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

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

我发现这个是因为在删除 MapHttpRoute 之后,我开始收到 404 not found,而当我添加 MapHttpRoute 时,可以找到资源。

更新:

我想出的解决这个问题的最终解决方案发布在这里: