Dynamic 如何在应用程序启动后动态添加OData Web Api路由?

Dynamic 如何在应用程序启动后动态添加OData Web Api路由?,dynamic,asp.net-web-api,routes,odata,Dynamic,Asp.net Web Api,Routes,Odata,我有一个需要动态添加OData路由的应用程序。我可以在应用程序启动后添加常规路由,但在使用OData路由时遇到问题 下面是我如何尝试动态添加ODataWebAPI路由的。在我的WebApiConfig中,我添加了一个产品路线: public static class WebApiConfig { public static void Register(HttpConfiguration config) { var builder = new ODataConven

我有一个需要动态添加OData路由的应用程序。我可以在应用程序启动后添加常规路由,但在使用OData路由时遇到问题

下面是我如何尝试动态添加ODataWebAPI路由的。在我的WebApiConfig中,我添加了一个产品路线:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var builder = new ODataConventionModelBuilder();
        builder.EntitySet<Product>("Products");
        config.MapODataServiceRoute(routeName: "ProductsRoute", routePrefix: "odata", model: builder.GetEdmModel());
    }
}
WebApiConfig.AddOrderRoute方法被正确调用并执行,无错误:

public static void AddOrderRoute(HttpConfiguration config)
{
    var builder = new ODataConventionModelBuilder();
    builder.EntitySet<Order>("Orders");
    config.MapODataServiceRoute(routeName: "OrdersRoute", routePrefix: "odata", model: builder.GetEdmModel());
    config.EnsureInitialized();
}
请注意,我正在AddOrderRoute中调用
config.EnsureInitialized()

我错过了什么


注意:如果我在WebApiConfig.Register()方法的末尾调用AddOrderRoute,我的订单路由可用且正常工作,因此我知道我的订单实体、上下文和控制器工作正常。只有当我在应用程序初始化完成后调用它时,我才发现问题。

正如我们在评论中所说的,同一路线的多个实体:

public static void Register(HttpConfiguration config)
{
    var builder = new ODataConventionModelBuilder();
    builder.EntitySet<Product>("Products");
    builder.EntitySet<Order>("Orders");
    config.MapODataServiceRoute(routeName: "OData", routePrefix: "odata", model: builder.GetEdmModel());
}

嗯,我在MSDN花了一些时间和好人在一起,得到了一个答案

以下是订单实体路线需要注册的方式:

var builder = new ODataConventionModelBuilder();
builder.EntitySet<Order>("Orders");

var route = config.Routes.Where(r => r is System.Web.OData.Routing.ODataRoute).First();
var odataRoute = route as System.Web.OData.Routing.ODataRoute;

config.MapODataServiceRoute(
    routeName: "OrdersRoute", 
    routePrefix: "odata", 
    model: builder.GetEdmModel(),
    pathHandler: odataRoute.PathRouteConstraint.PathHandler,
    routingConventions: odataRoute.PathRouteConstraint.RoutingConventions);
var builder=new ODataConventionModelBuilder();
建造商实体集(“订单”);
var route=config.Routes.Where(r=>r是System.Web.OData.Routing.ODataRoute.First();
var odataRoute=路由为System.Web.OData.Routing.odataRoute;
config.MapODataServiceRoute(
routeName:“OrdersRoute”,
routePrefix:“odata”,
模型:builder.GetEdmModel(),
pathHandler:odataRoute.PathRouteConstraint.pathHandler,
路由约定:odataRoute.PathRouteConstraint.routingConventions);

很好。现在可以访问…/odata/订单了,没问题。

我可以知道为什么要动态添加路线吗?考虑到一条路径可以服务于多个实体集,我们事先并不知道这些实体。用户指定新实体,然后我们允许他们在运行时对新实体执行CRUD操作。因此,我们期望的方法是在运行时(应用程序启动后)为其指定的实体创建新的odata路由。有趣的问题是,我们是否可以在应用程序启动后向同一路线添加新实体。不确定我们将如何从同一路径访问多个实体…这将引入在运行时创建CLR类型,例如,您最初有产品类型,用户创建订单,然后您需要有订单类型。这很难实施。在我看来,用户创建实例而不是类型是合理的。对于同一路线的多个实体,我将把它放在答案中。谢谢你的回答。问题是在应用程序启动时类型未知。我已经解决了使用CodeDom在运行时创建新CLR类型的问题。我唯一剩下的问题是将它们作为odata实体集提供。这意味着您必须在应用程序启动期间添加odata路由,然后重新使用其PathHandler和RoutingConventions?您知道如何在添加odata路由后动态删除它吗?哇,真是一场噩梦。OData名称空间非常糟糕。
public static void Register(HttpConfiguration config)
{
    var builder = new ODataConventionModelBuilder();
    builder.EntitySet<Product>("Products");
    builder.EntitySet<Order>("Orders");
    config.MapODataServiceRoute(routeName: "OData", routePrefix: "odata", model: builder.GetEdmModel());
}
1. http:///odata/Products and 
2. http:///odata/Orders
var builder = new ODataConventionModelBuilder();
builder.EntitySet<Order>("Orders");

var route = config.Routes.Where(r => r is System.Web.OData.Routing.ODataRoute).First();
var odataRoute = route as System.Web.OData.Routing.ODataRoute;

config.MapODataServiceRoute(
    routeName: "OrdersRoute", 
    routePrefix: "odata", 
    model: builder.GetEdmModel(),
    pathHandler: odataRoute.PathRouteConstraint.PathHandler,
    routingConventions: odataRoute.PathRouteConstraint.RoutingConventions);