没有注册非OData HTTP路由

时间:2017-02-28 22:16:07

标签: c# asp.net-web-api odata

我按照this教程创建了一个WebAPI REST服务。

之后,我可以通过指向http://baseaddress/api/Contacts加载所有联系人的列表。

然后我在WebApiConfig.cs的Register方法中添加了以下代码,以便启用OData端点:

config.Count().Filter().OrderBy().Expand().Select().MaxTop(null);

ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Contact>("Contacts");
config.MapODataServiceRoute(
    routeName: "OData",
    routePrefix: "odata",
    model: builder.GetEdmModel());

并在[EnableQuery]方法中添加了Contact.GetContacts()参数。这样,我就可以查询这样的特定联系人:

http://baseaddress/odata/Contacts?$filter=startswith(Name,'A')

它就像魅力一样。

不幸的是,当我放置[EnableQuery]时,WebAPI端点停止工作,显示以下错误:

No non-OData HTTP route registered.

in System.Web.OData.Extensions.HttpConfigurationExtensions.GetNonODataRootContainer(HttpConfiguration configuration)
in System.Web.OData.Extensions.HttpRequestMessageExtensions.GetRootContainer(HttpRequestMessage request, String routeName)
in System.Web.OData.Extensions.HttpRequestMessageExtensions.CreateRequestScope(HttpRequestMessage request, String routeName)
in System.Web.OData.Extensions.HttpRequestMessageExtensions.CreateRequestContainer(HttpRequestMessage request, String routeName)
...

我该怎么做才能解决这个问题?

10 个答案:

答案 0 :(得分:23)

我遇到了这个问题,因为我正在使用依赖注入,我设法通过将GlobalConfiguration.Configuration.EnableDependencyInjection()添加到startup.cs

来解决此问题

离。

using System.Web.OData.Extensions;
public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        GlobalConfiguration.Configuration.EnableDependencyInjection();
    }
}

答案 1 :(得分:4)

config.EnableDependencyInjection()中添加Startup.cs对我有用。

var config = new HttpConfiguration();

config.EnableDependencyInjection();

答案 2 :(得分:3)

此问题的关键是在.EnableDependencyInjection()的{​​{1}}方法上使用Configure

如果您使用的是ASP.net Core 端点路由(如果您使用 至少具有.net core 3.0和Microsoft.AspNetCore.OData v7.4.0)

Startup.cs

否则,如果您使用的是 MVC路由(仅.net之前可用) 核心3.0和Microsoft.AspNetCore.OData v7.4.0)

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();

    endpoints.Select().Filter().OrderBy().Count().MaxTop(10);
    endpoints.EnableDependencyInjection();//This guy solves the problem    
    endpoints.MapODataRoute("odata", "odata", GetEdmModel());
});

进一步阅读:https://devblogs.microsoft.com/odata/enabling-endpoint-routing-in-odata/

答案 3 :(得分:2)

我之前遇到过这个问题,并且通过添加下面的行为我工作

protected void Application_Start()
            {  
         GlobalConfiguration.Configuration.EnableDependencyInjection();
             ....  }

答案 4 :(得分:1)

将我的WebApi项目依赖项(NuGet)更新为:

  • Microsoft.AspNet.OData,版本=“ 7.0.1”
  • Microsoft.OData.Core,版本=“ 7.5.0”
  • Microsoft.OData.Edm,版本=“ 7.5.0”
  • Microsoft.Spatial,版本=“ 7.5.0”

降级到我以前使用的版本后,错误再次消失:

  • Microsoft.AspNet.OData,版本=“ 5.8.0”
  • Microsoft.OData.Core,版本=“ 6.19.0”
  • Microsoft.OData.Edm,版本=“ 6.19.0”
  • Microsoft.Spatial,版本=“ 6.19.0”

答案 5 :(得分:1)

我通过这种方式解决的问题:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
       .... existing code...

        //added:
        //(OData need this)
        config.EnableDependencyInjection();
        config.Expand().Select().OrderBy().Filter();
    }
}

答案 6 :(得分:0)

在我的情况下,即使我有一个单独的项目,根本没有Odata代码,我也遇到了上述错误。所以这是一个非常奇怪的消息。

我的解决方法是删除packages文件夹中的所有软件包。之后它再次起作用。一些Odata包仍在此文件夹中。

答案 7 :(得分:0)

就我而言,我有一个包含ODATA路由(和控制器)和其他API路由(和控制器)的网站。发生的事情是我的其他路由与ODATA路由完全冲突,即使使用不同的C#名称空间和类等也是如此。

最初,我的控制器就是这样的:

public class UserController : ApiController
{
    [HttpPost]
    public void Create([FromBody] string email)
    {
    }
}

我在ODATA中的某个地方(不同的名称空间,不同的url等)也有一条“用户”路由。因此,我必须明确地添加Route属性,如下所示:

public class UserController : ApiController
{
    [HttpPost]
    [Route("api/user/create")]
    public void Create([FromBody] string email)
    {
    }
}

答案 8 :(得分:0)

我也遇到了这个错误,就我而言,这是一个区分大小写的问题。我打过电话

https://www.example.com/odata/MyEntities代替

https://www.example.com/odata/myentities,因为它已注册。

请务必检查您的路由配置和调用网址。

答案 9 :(得分:0)

控制器名称必须与您在 builder.EntitySet<SomeType>() 中输入的名称相匹配

public class Startup
{
    public void Configuration(IAppBuilder appBuilder)
    {
        var config = new HttpConfiguration();

        config.Count().Filter().OrderBy().Expand().Select();

        var builder = new ODataConventionModelBuilder();
        builder.EntitySet<Order>("Order");// now the controller must be named OrderController
        
        config.MapODataServiceRoute(routeName: "odata", routePrefix: null, model: builder.GetEdmModel());
        
        appBuilder.UseWebApi(config);
    }
}

public class OrderController : ODataController
{
    // test data source
    public List<Order> OrdersList { get; set; } = new List<Order>()
    {
        // put some test data
    };

    [HttpGet]
    [EnableQuery]
    public IQueryable<Order> Get() //Get: http://localhost:port/Order
    { 
        return Orders.AsQueryable();
    }

    [HttpGet]
    [EnableQuery]
    public Order Get(int key) //Get: http://localhost:port/Order(key)
    {
        return Orders.FirstOrDefault(x => x.ID == key); 
    }

    [HttpPost]
    public bool Post(Order entity) //Post: http://localhost:port/Order
    {
        Orders.Add(entity);
        return true;
    }

    [HttpPut]
    public bool Put(int key, Order entity) //Put: http://localhost:port/Order(key)
    {
        var idx = Orders.FindIndex(x => x.ID == key);
        Orders[idx] = entity;
        return true;
    }

    [HttpPatch]
    public bool Patch(int key, Order entity) //Patch: http://localhost:port/Order(key)
    {
        var idx = Orders.FindIndex(x => x.ID == key);
        Orders[idx] = entity;
        return true;
    }

    [HttpDelete]
    public bool Delete(int key) //Delete: http://localhost:port/Order(key)
    {
        var idx = Orders.FindIndex(x => x.ID == key);
        Orders.RemoveAt(idx);
        return true;
    }
}

PS:我使用的是 Microsoft.AspNet.OData 7.5.5