对于某些方法,基于属性的webapi2路由返回404

rhe*_*one 8 c# asp.net-web-api asp.net-web-api-routing asp.net-web-api2

我目前正在开发一个已从Webapi升级到Webapi2的项目.部分转换包括切换到使用基于属性的路由.

我在Global.asax中设置了我的路线(如下)

 GlobalConfiguration.Configure(config => config.MapHttpAttributeRoutes());
Run Code Online (Sandbox Code Playgroud)

并删除了以前的路由配置.

我使用适当的System.Web.Http.RouteAttributeSystem.Web.Http.RoutePrefixAttribute属性装饰了所有API控制器.

如果我使用调试器检查System.Web.Http.GlobalConfiguration.Configuration.Routes,我可以看到所有我期望的路由都在集合中注册.同样,所包含的生成的Webapi帮助页面文档中也提供了适当的路径.

即使所有似乎都设置正确,我的REST调用数量也会导致服务器发现404未找到响应.

我发现了一些与GE​​T方法相关的显着相似之处(这是迄今为止我测试的所有内容)

  • 如果方法接受0参数,它将失败
  • 如果路由覆盖前缀,则会失败
  • 如果方法采用字符串参数,则可能会成功
  • 返回类型似乎没有影响
  • 命名路线似乎没有任何影响
  • 订购路线似乎没有任何影响
  • 重命名基础方法似乎没有任何影响

值得注意的是,我的API控制器出现在一个单独的区域,但考虑到某些路由可行,我不认为这是手头的问题.

非功能方法调用的示例

[RoutePrefix("api/postman")]
public class PostmanApiController : ApiController
{
    ...
    [HttpGet]
    [Route("all", Name = "GetPostmanCollection")]
    [ResponseType(typeof (PostmanCollectionGet))]
    public IHttpActionResult GetPostmanCollection()
    {
        return Ok(...);
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

我希望这可以通过 http://[application-root]/api/postman/all

有趣的是打电话给

Url.Link("GetPostmanCollection", null)
Run Code Online (Sandbox Code Playgroud)

将返回上述预期的网址

一个非常类似的方法调用示例在同一个控制器中调用,其中一些工作,一些不工作.

[RoutePrefix("api/machine")]
public class MachineApiController : ApiController
{
    ...
    [HttpGet]
    [Route("byowner/{owner}", Name = "GetPostmanCollection")]
    public IEnumerable<string> GetByOwner([FromUri] string owner)
    {
        ...
    }
    ...

    [HttpGet]
    [Route("~/api/oses/{osType}")]
    public IEnumerable<OsAndVersionGet> GetOSes([FromUri] string osType)
    {
        ...
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

哪里有http://[application-root]/api/machineby/ownername 成功而http://[application-root]/api/oses/osType没有成功.

我一直在讨论这个问题太久了,不知道问题可能是什么?

mt_*_*erg 13

MapHttpAttributeRoutes任何 ASP.NET MVC路由注册之前,请检查是否通过该方法配置了HttpConfiguration .

根据Microsoft 在MVC和Web API中属性路由的CodePlex条目,设计部分指出:

在大多数情况下,首先调用MapHttpAttributeRoutes或MapMvcAttributeRoutes,以便在全局路由之前注册属性路由(因此有机会取代全局路由).属性路由控制器的请求也将仅过滤到源自属性路由的请求.

因此,在Global.asax(或注册路线的地方)内拨打电话是合适的:

GlobalConfiguration.Configure(c => c.MapHttpAttributeRoutes()); // http routes
RouteTable.Routes.MapRoute(...); // mvc routes
Run Code Online (Sandbox Code Playgroud)

  • @MoonStom:你不对.Globalconfiguration.Configure()将适当的WebApi HttpConfiguration传递给回调.重要的是,MapHttpAttributeRoutes()必须在任何MapRoute()或MapHttpRoute()调用之前调用. (2认同)

fah*_*ash 6

在我的情况下,这是一个愚蠢的错误,我发布了这个错误,因此在我身后犯同样错误的人们在阅读量子级的所有其他内容之前都先阅读了此错误。

我的错误是,控制人的名字没有以单词结尾Controller

新年快乐