【问题标题】: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

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


【解决方案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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-06
    • 2013-05-24
    • 2013-01-22
    • 2013-10-22
    • 1970-01-01
    相关资源
    最近更新 更多