为什么我的 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}
:存在电子邮件
?email
:info@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
中的 RoutePrefix
和 Route
属性。
根据您配置的两个路由约定,以下 URI 也应与您的操作方法相匹配(它们应该是等效的):
https://localhost:44300/api/accountapi?email=info@something.com
https://localhost:44300/api/MyArea/accountapi?email=info@something.com
我的建议是避免使用太多不同的路由模板和配置:如果您需要最大的灵活性,请仅使用属性路由并删除基于约定的路由配置。
我在自定义区域中有一个 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}
:存在电子邮件?email
:info@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
中的 RoutePrefix
和 Route
属性。
根据您配置的两个路由约定,以下 URI 也应与您的操作方法相匹配(它们应该是等效的):
https://localhost:44300/api/accountapi?email=info@something.com
https://localhost:44300/api/MyArea/accountapi?email=info@something.com
我的建议是避免使用太多不同的路由模板和配置:如果您需要最大的灵活性,请仅使用属性路由并删除基于约定的路由配置。