3

使用 .NET 4.5.1、Web API 2、Visual Studio 2013:

我有一个具有以下路由的 Web API...

  • /api/提供者/专业
  • /api/providers/specialties/123
  • /api/提供者/专业/医学

这些按预期工作......第一个获得所有专业的列表,第二个获得专业 ID 123,第三个获得名称中包含“医学”的所有专业。

我也有这些路线...

  • /api/位置/专业
  • /api/locations/specialties/123
  • /api/位置/专业/正交

只有最后两个工作......第一个返回此错误:

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'

怎么会这样?它将命中该控制器中的其他路由,而不是基础路由。

(我还有另外两个控制器,它们自己的路由/api/providers/api/locations工作正常。)

这是ProviderSpecialtyController.cs代码:

[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);
    }
}

这是LocationSpecialtyController.cs代码:

[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);
    }
}

如您所见,除了路由前缀之外,它们几乎相同。为什么提供者控制器按预期工作,而位置控制器却没有?

我已启用跟踪,并在尝试点击/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.
4

1 回答 1

1

这比看起来更简单,但是由于调试不佳(这是由Kiran Challa在 Codeplex中提交并验证为错误),因此确定原因变得更加困难。这应该从 Web API 2.1 开始修复。

我有一个带有这条路线的控制器:

/api/locations/keyword

哪个会在keyword.

我有另一个带有这些路由的控制器:

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

API 引擎很困惑,因为我有两个具有基本相同路由的控制器。我删除了一个,问题得到解决。

根据 Codeplex 问题跟踪器,该问题已得到验证、关闭,并在Web API 2.1中添加了新的错误消息。

于 2014-05-06T17:37:44.290 回答