为啥我的 Web API 对所有内容都返回 405?

Posted

技术标签:

【中文标题】为啥我的 Web API 对所有内容都返回 405?【英文标题】:Why does my Web API return 405 for everything?为什么我的 Web API 对所有内容都返回 405? 【发布时间】:2016-09-24 05:23:54 【问题描述】:

我在自定义区域中有一个 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":"请求的资源不支持http方式 '得到'。"

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

也返回 405。

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

有什么想法吗?

【问题讨论】:

能否请您显示调用此 API 的代码?这很可能是因为您使用 type: "POST" 进行 API 调用。 不,对不起,我不是。我明确地从我的客户那里做 GET。 您为您的区域添加常规路线和属性路线是否有原因?无论如何,您指定的常规路由 (api/MyArea/controller/id) 与控制器上的属性路由 (myarea/api/accountapi) 之间存在不匹配(区域和 api 段已切换) )。我认为属性路由会覆盖任何常规路由,因此您需要在当前配置中使用的 url 是 GET https://localhost:44300/myarea/api/accountapi/emailexists?email=a@email.com 【参考方案1】:

让我们分析您正在调用的端点。

第一个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(出于路由目的,这将被忽略,因为它不包含在模板中)

查看您的AccountAPIController,我看不到任何允许GETAction,并且还有一个名为(显式)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

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

【讨论】:

以上是关于为啥我的 Web API 对所有内容都返回 405?的主要内容,如果未能解决你的问题,请参考以下文章

Cors 中启用的所有标头,WebConfig 和 WebApiConfig 之间没有冲突,为啥我的 WebApi 返回 405 错误?

ASP.NET Core Web API DELETE 调用返回 405

为啥 Discord API 返回错误 405 以向公会添加斜杠命令?

405 方法不允许 Web API

为啥我的 post 请求返回 405 错误? [复制]

发布 Web API 2 应用程序后的 HTTP 405 错误