网页API 2路由在一个控制器属性的工作,但不是另一个 [英] Web API 2 routing attributes work in one controller but not another

查看:197
本文介绍了网页API 2路由在一个控制器属性的工作,但不是另一个的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用.NET 4.5.1,网页API 2时,Visual Studio 2013:

我有一个网页API,具有以下路线...


  • / API /供应商/专业

  • / API /供应商/专业/ 123

  • / API /供应商/专业/医药

如预期这些工作......第一个得到所有专业的列表,第二个得到专业ID 123,第三个在名称得到所有专业与药。

我也有这些线路...


  • / API /位置/专科

  • / API /位置/专业/ 123

  • / API /位置/专业/邻

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

 无HTTP资源发现匹配的请求URI [...]
不提供控制器名称找到路由匹配请求URI的http:// mysite的/ API /位置/特色菜

怎么能这样呢?它会打击其他途径在控制器,只是没有基地之一。

(我的还有其他两个控制器与路线的 / API /提供商 / API /位置按自己,这很好地工作。 )

下面是在 ProviderSpecialtyController.cs code:

  [路线preFIX(API /供应商/特产)]
公共类ProviderSpecialtyController:ApiController
{
    私人ProviderEntities DB =新ProviderEntities();    ///<总结>
    ///获取所有专业,按名称排序。
    ///< /总结>
    [路线()]
    公众的IQueryable< ProviderSpecialty>得到()
    {
        返回db.ProviderSpecialties.OrderBy(S => s.Name);
    }    ///<总结>
    ///获取特定的特产。
    ///< /总结>
    ///< PARAM NAME =ID>一种特别的专业的ID< /参数>
    [路线({ID:INT})]
    公共ProviderSpecialty获取(INT ID)
    {
        返回db.ProviderSpecialties.Where(S => s.Id ==内径).FirstOrDefault();
    }    ///<总结>
    ///获取包含关键字的所有特色。
    ///< /总结>
    ///< PARAM NAME =关键词方式>的关键字在一个专业名称搜索< /参数>
    [路线({关键字:阿尔法})]
    公众的IQueryable< ProviderSpecialty>获取(字符串关键字)
    {
        返回db.ProviderSpecialties.Where(S = GT; s.Name.Contains(关键字))。排序依据(S = GT; s.Name);
    }
}

这是在 LocationSpecialtyController.cs code:

  [路线preFIX(API /位置/特产)]
公共类LocationSpecialtyController:ApiController
{
    私人ProviderEntities DB =新ProviderEntities();    ///<总结>
    ///获取所有专业,按名称排序。
    ///< /总结>
    [路线()]
    公众的IQueryable< LocationSpecialty>得到()
    {
        返回db.LocationSpecialties.OrderBy(S => s.Name);
    }    ///<总结>
    ///获取特定的特产。
    ///< /总结>
    ///< PARAM NAME =ID>一种特别的专业的ID< /参数>
    [路线({ID:INT})]
    公共LocationSpecialty获取(INT ID)
    {
        返回db.LocationSpecialties.Where(S => s.Id ==内径).FirstOrDefault();
    }    ///<总结>
    ///获取包含关键字的所有特色。
    ///< /总结>
    ///< PARAM NAME =关键词方式>的关键字在一个专业名称搜索< /参数>
    [路线({关键字:阿尔法})]
    公众的IQueryable< LocationSpecialty>获取(字符串关键字)
    {
        返回db.LocationSpecialties.Where(S = GT; s.Name.Contains(关键字))。排序依据(S = GT; s.Name);
    }
}

正如你可以看到,他们除了路线preFIX几乎相同。为什么像预期的那样提供控制器工作,但位置的控制器不?

我已经启用了跟踪,并试图打的 / API /位置/特产时,观察到以下

  System.Web.Http.Request:GET HTTP://本地主机:49565 / API /位置/专业/:分类= System.Web.Http.Request,级别=信息开始HTTP://本地主机:49565 / API /位置/专业/
System.Web.Http.Controllers:GET HTTP://本地主机:49565 / API /位置/专业/:分类= System.Web.Http.Controllers,级别=信息开始DefaultHttpControllerSelector SelectController路线='MS_SubRoutes:System.Web.Http .Routing.IHttpRouteData []'
[...]
System.Web.Http.Controllers:GET HTTP://本地主机:49565 / API /位置/专业/:分类= System.Web.Http.Controllers,HTTP请求的水平=错误结束DefaultHttpControllerSelector SelectController处理导致异常。请看到这个异常的详细信息的响应属性返回的HTTP响应。


解决方案

这比它似乎简单,但确定为什么有人通过调试差(是的提出并验证通过的 =http://stackoverflow.com/users/1184056/kiran- challa>基兰Challa 的。这应该是固定的为Web API 2.1。

我曾与这条路线的控制器:

  / API /位置/关键字

这将做关键字关键字搜索

我曾与这些路线另一个控制器:

  / API /位置/特产
/ API /位置/专业/ 123
/ API /位置/专业/关键字

该API引擎被搞糊涂了,因为我有两个控制器,本质上是相同的路线。我删除了一个,问题是固定的。

按照codePLEX问题跟踪,这个问题进行了验证,关闭,在的网络API 2.1

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.

解决方案

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.

这篇关于网页API 2路由在一个控制器属性的工作,但不是另一个的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆