Web API: Odata route always returning a 404 response

6.4k views Asked by At

I am new to OData. I have built an ASP.NET Web API controller as shown below:

using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Web.OData.Routing;

namespace HelloWebApi.Controllers
{
  public class TestsController : ODataController
  {
    ProductsContext db = new ProductsContext();
    private bool TestExists(int key)
    {
      return db.tests.Any(p => p.key== key);
    }
    protected override void Dispose(bool disposing)
    {
      db.Dispose();
      base.Dispose(disposing);
    }

    [EnableQuery]
    public IQueryable<test> Get()
    {
      return db.tests;
    }
  }
}

The model is as shown below:

public class Test
{
  [Key]
  public int key { get; set; }
  public string aaa { get; set; }
}

I have also configured the RouteConfig, ODdataConfig, and WebApiConfig as shown below:

public class RouteConfig
{
  public static void RegisterRoutes(RouteCollection routes)
  {
    routes.Ignore("{resource}.axd/{*pathInfo}");
    routes.MapHttpRoute(
      name: "Default",
      routeTemplate: "{controller}/{action}/{id}"
    );
  }
}

public class ODataConfig
{
  public static void Register(HttpConfiguration config)
  {
    // Web API routes
    config.MapHttpAttributeRoutes();
    ODataModelBuilder builder = new ODataConventionModelBuilder();
    builder.EntitySet<Test>("Tests");
    config.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());
  }
}

public static class WebApiConfig
{
  public static void Register(HttpConfiguration config)
  {
    config.Routes.MapHttpRoute(
      name: "DefaultApi",
      routeTemplate: "api/{controller}/{id}",
      defaults: new { id = RouteParameter.Optional }
    );           

  }
}

As well as the global.asax file:

public class WebApiApplication : System.Web.HttpApplication
{
  protected void Application_Start()
  {
    GlobalConfiguration.Configure(config =>
    {
      ODataConfig.Register(config); //this has to be before WebApi
      WebApiConfig.Register(config);
    });
    //FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
  }
}

I tried making a number of modifications in order to resolve this. But I am consistently getting an HTTP 404 Not Found response. I also tried explicitly adding an [ODataRoute] attribute to the action method name; when doing that I instead get an HTTP 406 Not Acceptable response.

The URL I am trying to configure is:

http://localhost:6701/odata/tests/

Where odata is the suffix and tests is the controller name. Please point out what I am doing wrong.

1

There are 1 answers

7
Jeremy Caney On BEST ANSWER

The routes configured by the ODataConventionModelBuilder are case-sensitive. In your code, you have defined:

builder.EntitySet<Test>("Tests");

Based on this, the endpoint will be:

http://localhost:6701/odata/Tests/

Note the upper-case T in Tests.

This is by design, in order to maintain compatibility with the OData specification.

That said, as of Web API OData 5.4, you can optionally enable case-insensitive routes using the HttpConfiguration class's EnableCaseInsensitive() method. E.g., in your ODataConfig.Register() method you could add:

config.EnableCaseInsensitive(caseInsensitive: true);

For more information, see Basic Case Insensitive Support under Microsoft's ASP.NET Web API for OData V4 Docs.