为什么我的Web API会为所有内容返回405?

时间:2016-05-26 09:33:44

标签: asp.net-web-api asp.net-mvc-areas http-status-code-405

我在自定义区域中有一个ASP.NET Web API 2控制器。 (我在默认路由中也有一些API控制器)

我已注册路线:

// Web API routes
config.MapHttpAttributeRoutes();

// NEW ROUTE FOR AREAS
config.Routes.MapHttpRoute(
    name: "API Area MyArea",
    routeTemplate: "api/MyArea/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional });

我的控制器和方法:

 [RoutePrefix("myarea/api/accountapi")]
  public class AccountAPIController : ApiController
  {
...

    [System.Web.Http.HttpGet]
    [AcceptVerbs("GET")]
    [AllowAnonymous]
    [Route("emailexists")]
    public async Task<IHttpActionResult> EmailExsists([FromUri]string email)
    {
      var user = await UserManager.FindByEmailAsync(email).ConfigureAwait(false);
      return Ok(user != null);
    }
...
}

但无论我尝试得到什么,我都无法让它发挥作用: https://localhost:44300/api/accountapi/emailexists?email=info@something.com

  

{&#34; message&#34;:&#34;请求的资源不支持http方法   &#39; GET&#39;&#34;}

事实上,我无法让它返回预期的404.例如,这: https://localhost:44300/api/accountapi/jibberish

还返回405。

默认路由中的我的API控制器按预期工作,即应该返回404。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

让我们分析您正在呼叫的端点。

第一个URI:

https://localhost:44300/api/accountapi/emailexists?email=info@something.com

查看您的路由配置,这将仅匹配api/{controller}/{id}路由模板。这是因为第一个约定路由配置只匹配以api/MyArea开头的URI部分,而控制器的属性路由前缀只匹配以myarea/api/accountapi开头的路径。

这将转换为以下路线属性:

  • {controller} accountapi
  • {id} emailexists
  • ?email info@something.com 路由目的会因此而忽略,因为模板中未包含此内容)

查看您的AccountAPIController我无法看到允许Action的任何GET,并且还有一个名为(显式)id的字符串参数:因此405归还。

第二个URI:

https://localhost:44300/api/accountapi/jibberish

将再次匹配与之前相同的路线模板:

  • {controller} accountapi
  • {id} jibberish

出于同样的原因,返回405响应。

怎么做?

您的主要问题是您正在混合使用不同的路由方法而未正确匹配您的操作的URI。在不修改当前路由配置的情况下,EmailExsists方法的正确地址如下:

https://localhost:44300/myarea/api/accountapi/emailexists?email=info@something.com

这符合RoutePrefix中的RouteAccountAPIController属性。

以下URI也应该基于您配置的两个路由约定(它们应该是等效的)匹配您的操作方法:

https://localhost:44300/api/accountapi?email=info@something.com
https://localhost:44300/api/MyArea/accountapi?email=info@something.com

我的建议是避免使用太多不同的路由模板和配置:如果您需要最大的灵活性,请仅使用属性路由并删除基于约定的路由配置。