为什么我的 Web API return 一切都是 405?

Why does my Web API return 405 for everything?

我在自定义区域中有一个 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

{"message":"The requested resource does not support http method 'GET'."}

事实上,我无法将其设置为 return 预期的 404。例如,这个: https://localhost:44300/api/accountapi/jibberish

还有 return405。

我的 API 默认路由中的控制器按预期工作,即 return 在应该的时候发送 404。

有什么想法吗?

让我们分析一下您调用的端点。

第一个 URI:

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

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

开头的路径。

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

  • {controller}: accountapi
  • {id}存在电子邮件
  • ?emailinfo@something.com(对于 routing 目的,这将被忽略,因为不包括在内在模板中)

查看您的 AccountAPIController 我看不到任何 Action 允许 GET 并且还有一个字符串参数(明确地)称为 id:因此是 405返回。

第二个 URI:

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

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

  • {controller}: accountapi
  • {id}: 胡言乱语

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

怎么办?

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

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

这将匹配您在 AccountAPIController 中的 RoutePrefixRoute 属性。

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

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

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