ASP.NET Web Api:所请求的资源不支持HTTP方法“GET”。

101

我在一个ApiController中有以下操作:

public string Something()
{
    return "value";
}

我已经按照以下方式配置了我的路由:

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

在beta版本中,这个功能完美运行,但我刚更新到最新的发布候选版,现在我看到像这样的调用错误:

请求的资源不支持http方法'GET'。

为什么它不再起作用了?

(我想我可以去掉{action}并创建大量的控制器,但那感觉很混乱。)

11个回答

115

如果你没有在控制器的操作中配置任何HttpMethod,那么在RC中默认为仅支持HttpPost。在Beta版本中,它被认为支持所有方法 - GET,PUT,POST和Delete。从Beta到RC这是一个小改变。你可以使用[AcceptVerbs("GET", "POST")]来简单地装饰你的操作并支持多个httpmethod。


刚刚遇到这个问题,感谢修复,但是我很好奇,为什么我必须对我的自定义方法这样做,而不是默认的“Get”方法?我有一个由控制器模板创建的Get方法,但它没有被装饰。这只是因为名称是Get的惯例吗? - SelAromDotNet
5
@Josh: 是的!当动作方法的名称以“Get...”开头时,你不必将其标记为GET方法。在这里阅读更多信息:http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api - Krisztián Balla
我按照答案中建议的做了,但现在我的Get和Post调用都被重定向到Get Action。请帮忙解决一下? - Syed Ali Taqi

56

以上所有信息都是正确的,我还想指出 [AcceptVerbs()] 注释存在于 System.Web.Mvc 和 System.Web.Http 命名空间中。

如果是 Web API 控制器,您应该使用 System.Web.Http。


35
虽然这不是对楼主的回答,但我曾因完全不同的原因遇到了完全相同的错误;所以如果有人需要,希望可以帮上忙...
我的问题是方法参数名称不正确,这导致WebAPI意外地路由请求。我在我的ProgrammesController中有以下方法:
[HttpGet]
public Programme GetProgrammeById(int id)
{
    ...
}

[HttpDelete]
public bool DeleteProgramme(int programmeId)
{
    ...
}

我原以为DELETE请求到... /api/programmes/3会被路由到DeleteProgramme,但实际上它们被路由到了GetProgrammeById,因为DeleteProgramme没有id参数名。当然,由于GetProgrammeById被标记为只接受GET请求,所以会拒绝DELETE请求。

所以修复很简单:

[HttpDelete]
public bool DeleteProgramme(int id)
{
    ...
}

一切都好了。其实是个愚蠢的错误,但很难调试。


1
如果有人正在使用URL路由,请尝试像这样做[Route("{programmeId=programmeId:int}")]。 - sree
1
这就是我的全部内容。WebApiConfig -> MapHttpRoutes 中有 routeTemplate: "api/{controller}/{id}",因此必须使用'id'参数。 - JsAndDotNet
1
你的回答指引了我找到问题所在,它与我的问题略有不同。我更改了方法中一个 [FromUri] 参数的名称,但没有在客户端更新它。 - Matus

30

如果你想在方法上使用 HttpGet,请在控制器顶部添加以下 using

using System.Web.Http;
如果您正在使用System.Web.Mvc,那么可能会出现此问题。

7
这是真的,而且非常荒谬。然而.NET没有清晰地显示该消息。 - Teoman shipahi
哇,这个真是奇怪!而且这位英雄来到这里发布了这个问题!‍♂️ - Ian Grainger

15

这绝对是从Beta到RC的变化。在问题提供的示例中,您现在需要使用[HttpGet]或[AcceptVerbs(“GET”)]来修饰您的操作。

如果您想将基于动词的操作(即“GetSomething”,“PostSomething”)与非动词的操作混合使用,则会出现问题。如果您尝试使用上面的属性,它将与控制器中的任何基于动词的操作产生冲突。解决这个问题的一种方法是为每个动词定义单独的路由,并将默认操作设置为该动词的名称。此方法可用于定义API中的子资源。例如,以下代码支持:“/resource/id/children”,其中id和children是可选的。

        context.Routes.MapHttpRoute(
           name: "Api_Get",
           routeTemplate: "{controller}/{id}/{action}",
           defaults: new { id = RouteParameter.Optional, action = "Get" },
           constraints: new { httpMethod = new HttpMethodConstraint("GET") }
        );

        context.Routes.MapHttpRoute(
           name: "Api_Post",
           routeTemplate: "{controller}/{id}/{action}",
           defaults: new { id = RouteParameter.Optional, action = "Post" },
           constraints: new { httpMethod = new HttpMethodConstraint("POST") }
        );

希望未来版本的Web API能更好地支持这种情况。目前,aspnetwebstack codeplex项目中记录了一个问题,http://aspnetwebstack.codeplex.com/workitem/184。如果您希望看到这一点,请在该问题上投票。


8

和OP有相同的设置。一个控制器有许多操作... 少些“混乱”:-)

在我的情况下,当添加新操作时,我忘记了“[HttpGet]”。

[HttpGet]
public IEnumerable<string> TestApiCall()
{
    return new string[] { "aa", "bb" };
}

7

与上述问题相同,但根本原因大不相同。对我来说,是因为我使用了一个https重写规则来访问端点。使用http访问时会出现错误,而使用https则能正常工作。


哇,我差点就要疯了,因为错误根本没有描述问题,谢谢! - kilkfoe

3

请将以下代码替换到以下路径:

路径:

App_Start => WebApiConfig.cs

代码:

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

2

在没有使用SSL的情况下运行查询时,我遇到了这个错误。

将请求的URL方案从HTTP更改为HTTPS即可解决问题。


@cizario 我不同意 - 它似乎是回答问题的尝试。我在这个问题上投了“看起来没问题”的票。 - EJoshuaS - Stand with Ukraine
@EJoshuaS-ReinstateMonica,这更像是一条评论而不是对问题的真正回答。根据被接受的答案和下面的其他答案,问题似乎与模式无关。 - cizario
@cizario 错误的答案并不是低质量的 - 如果您认为答案是错误的,应该将其投票下降。请参见:Are blatantly wrong answers very low quality? - EJoshuaS - Stand with Ukraine
@EJoshuaS-ReinstateMonica,你是对的,我已经删除了我的评论。 - cizario
好的,首先,谢谢!!!非常有效!!!现在,关于问题/答案,事实上,使用HTTP而不是HTTPS会导致问题标题中所述的错误,事实上我没有阅读实际的问题(正文),但这肯定是解决问题标题中所述问题的方法。 - Gabriel G

1
我不知道这是否与原帖有关,但我缺少[HttpGet]注释,这就是导致错误的原因,正如@dinesh_ravva所述,默认情况下认为方法是HttpPost。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接