Question

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.
Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top