3

Using .NET 4.5.1, Web API 2, Visual Studio 2013:

I have a Web API which has the following routes...

  • /api/providers/specialties
  • /api/providers/specialties/123
  • /api/providers/specialties/medicine

These work as expected... the first one gets a list of all specialties, the second one gets specialty ID 123, and the third gets all specialties with "medicine" in the name.

I also have these routes...

  • /api/locations/specialties
  • /api/locations/specialties/123
  • /api/locations/specialties/ortho

Only the last two work... the first one returns this error:

No HTTP resource was found that matches the request URI [...] No route providing a controller name was found to match request URI 'http://mysite/api/locations/specialties' 

How can this be? It will hit other routes in that controller, just not the base one.

(I also have two other controllers with the routes /api/providers and /api/locations by themselves, which work fine.)

Here is the ProviderSpecialtyController.cs code:

[RoutePrefix("api/providers/specialties")] public class ProviderSpecialtyController : ApiController { private ProviderEntities db = new ProviderEntities(); /// <summary> /// Get ALL specialties, sorted by name. /// </summary> [Route("")] public IQueryable<ProviderSpecialty> Get() { return db.ProviderSpecialties.OrderBy(s => s.Name); } /// <summary> /// Get a specific specialty. /// </summary> /// <param name="id">The ID of a particular specialty.</param> [Route("{id:int}")] public ProviderSpecialty Get(int id) { return db.ProviderSpecialties.Where(s => s.Id == id).FirstOrDefault(); } /// <summary> /// Get all specialties that contain a keyword. /// </summary> /// <param name="keyword">The keyword to search for in a specialty name.</param> [Route("{keyword:alpha}")] public IQueryable<ProviderSpecialty> Get(string keyword) { return db.ProviderSpecialties.Where(s => s.Name.Contains(keyword)).OrderBy(s => s.Name); } } 

And here is the LocationSpecialtyController.cs code:

[RoutePrefix("api/locations/specialties")] public class LocationSpecialtyController : ApiController { private ProviderEntities db = new ProviderEntities(); /// <summary> /// Get ALL specialties, sorted by name. /// </summary> [Route("")] public IQueryable<LocationSpecialty> Get() { return db.LocationSpecialties.OrderBy(s => s.Name); } /// <summary> /// Get a specific specialty. /// </summary> /// <param name="id">The ID of a particular specialty.</param> [Route("{id:int}")] public LocationSpecialty Get(int id) { return db.LocationSpecialties.Where(s => s.Id == id).FirstOrDefault(); } /// <summary> /// Get all specialties that contain a keyword. /// </summary> /// <param name="keyword">The keyword to search for in a specialty name.</param> [Route("{keyword:alpha}")] public IQueryable<LocationSpecialty> Get(string keyword) { return db.LocationSpecialties.Where(s => s.Name.Contains(keyword)).OrderBy(s => s.Name); } } 

As you can see, they are nearly identical except for the route prefix. Why does the provider controller work as expected but location controller does not?

I have enabled tracing and the following is observed when trying to hit /api/locations/specialties:

System.Web.Http.Request: GET http://localhost:49565/api/locations/specialties/: Category=System.Web.Http.Request, Level=Info Begin http://localhost:49565/api/locations/specialties/ System.Web.Http.Controllers: GET http://localhost:49565/api/locations/specialties/: Category=System.Web.Http.Controllers, Level=Info Begin DefaultHttpControllerSelector SelectController Route='MS_SubRoutes:System.Web.Http.Routing.IHttpRouteData[]' [...] System.Web.Http.Controllers: GET http://localhost:49565/api/locations/specialties/: Category=System.Web.Http.Controllers, Level=Error End DefaultHttpControllerSelector SelectController Processing of the HTTP request resulted in an exception. Please see the HTTP response returned by the 'Response' property of this exception for details. 
8
  • 1
    If you comment out your other controller which uses the /api/locations route, does the route work then? Commented Nov 11, 2013 at 19:30
  • Wow, you got me thinking on another wavelength and I discovered something that should have been obvious: In my /api/locations route, I allow a route /api/locations/keyword ... I'm sure that is confusing the system somehow. (I found this by doing as you suggested and commenting out the main /api/locations route, thank you!) Commented Nov 11, 2013 at 19:34
  • 1
    Just curious...are you sure you are using RoutePrefix and Route attributes from Web API and not from MVC...i ask this because based on your error message, looks like your request is being matched by Web API's traditional/conventional route...do you have any traditional route registered too? Commented Nov 11, 2013 at 19:42
  • 1
    One possible solution is to just add an extra segment to the api/locations/[keyword] route. Something like api/locations/search/[keyword]. Commented Nov 11, 2013 at 19:59
  • 1
    Just FYI...I filed a bug which is related to the issue you are noticing: aspnetwebstack.codeplex.com/workitem/1417 Commented Nov 14, 2013 at 17:56

1 Answer 1

1

This was simpler than it seemed, but determining why was made more difficult by poor debugging (which was filed and verified as a bug in Codeplex by Kiran Challa. This should be fixed as of Web API 2.1.

I had a controller with this route:

/api/locations/keyword 

Which would do a keyword search on keyword.

I had another controller with these routes:

/api/locations/specialties /api/locations/specialties/123 /api/locations/specialties/keyword 

The API engine was confused, because I had two controllers with essentially the same route. I removed one and the problem was fixed.

According to the Codeplex issue tracker, the issue was verified, closed and a new error message was added in Web API 2.1.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.