ChatGPT解决这个技术问题 Extra ChatGPT

405 方法不允许 Web API

这个错误很常见,我尝试了所有的解决方案,但没有一个有效。我在控制面板中禁用了 WebDAV 发布并将其添加到我的 Web 配置文件中:

  <handlers>
  <remove name="WebDAV"/>
  </handlers>
  <modules runAllManagedModulesForAllRequests="true">
  <remove name="WebDAVModule"/>
  </modules>

错误仍然存在。这是控制器:

   static readonly IProductRepository repository = new ProductRepository();

    public Product Put(Product p)
    {
        return repository.Add(p);
    }

方法实现:

 public Product Add(Product item)
    {
        if (item == null)
        {
            throw new ArgumentNullException("item");
        }
        item.Id = _nextId++;
        products.Add(item);
        return item;
    }

这就是引发异常的地方:

client.BaseAddress = new Uri("http://localhost:5106/");
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));      
var response = await client.PostAsJsonAsync("api/products", product);//405 exception

有什么建议么?


D
Darin Dimitrov

您正在从客户端发布:

await client.PostAsJsonAsync("api/products", product);

不放。

您的 Web API 方法只接受 PUT 请求。

所以:

await client.PutAsJsonAsync("api/products", product);

尝试您的代码时,会引发错误“HttpClient”不包含“PostAsJsonAsync”的定义。
B
Beatles1692

我也有同样的例外。我的问题是我使用过:

using System.Web.Mvc; // Wrong namespace for HttpGet attribute !!!!!!!!!
[HttpGet]
public string Blah()
{
    return "blah";
}

应该

using System.Web.Http; // Correct namespace for HttpGet attribute !!!!!!!!!
[HttpGet]
public string Blah()
{
    return "blah";
}

u
user2662006

我尝试了很多方法来让 DELETE 方法工作(我得到 405 方法不允许 web api),最后我将 [Route("api/scan/{id}")] 添加到我的控制器并且工作正常。希望这篇文章对某人有所帮助。

     // DELETE api/Scan/5
    [Route("api/scan/{id}")]
    [ResponseType(typeof(Scan))]
    public IHttpActionResult DeleteScan(int id)
    {
        Scan scan = db.Scans.Find(id);
        if (scan == null)
        {
            return NotFound();
        }

        db.Scans.Remove(scan);
        db.SaveChanges();

        return Ok(scan);
    }

出于某种原因,我的它仅不适用于删除,创建和更新它工作正常。好吧,我刚刚添加了 [HttpPost] 并且它起作用了。但是谢谢,你让我走上了正确的道路,现在只花了我 5 分钟 :)
你为什么不只是添加 [HttpDelete] 属性?
N
Nexxas

我的问题原来是 WebAPI 中的属性路由。我创建了一个自定义路由,它把它当作一个 GET 而不是 WebAPI 发现它是一个 POST

    [Route("")]
    [HttpPost] //I added this attribute explicitly, and it worked
    public void Post(ProductModel data)
    {
        ...
    }

我知道这一定很愚蠢(这会消耗你一整天)


N
Nate Zaugg

Chrome 经常尝试在发布帖子之前进行 OPTIONS 调用。它这样做是为了确保 CORS 标头是有序的。如果您不在 API 控制器中处理 OPTIONS 调用,则可能会出现问题。

public void Options() { }

F
FrankyHollywood

当您在服务器处于 https 时尝试连接到 http 时,也会发生此错误。

这有点令人困惑,因为我的 get-requests 没问题,问题只存在于 post-requests 中。


有没有办法在不将 URL 从 http 更改为 https 的情况下解决这个问题?
这是我遇到的问题。谢谢
S
Sako73

我在 GET 调用中收到 405,问题是我将 GET 服务器端方法中的参数命名为 Get(int formId),我需要更改路由或将其重命名为 Get(int id)


T
Tom Stickel

如果您的方法需要一个参数并且您没有传递它,您也可能会收到 405 错误。

这不起作用(405错误)

HTML 视图/Javascript

$.ajax({
         url: '/api/News',
         //.....

网络接口:

public HttpResponseMessage GetNews(int id)

因此,如果方法签名与上述类似,那么您必须执行以下操作:

HTML 视图/Javascript

$.ajax({
         url: '/api/News/5',
         //.....

由于各种原因,我似乎遇到了 405 错误,它们都归结为它试图命中方法签名和参数问题或约定命名问题或属性问题等的事实......
k
ketan

我参加这个聚会迟到了,但在大多数情况下,以上任何内容都不可行或有效,这就是我最终解决的方法。

在托管站点/服务的服务器上,需要一个功能! HTTP 激活!!!

Server Manager > Manage > Add Roles and Features > next next next 直到您到达 Features > Under .NET(每个版本)勾选 HTTP Activation。另请注意,>net > WCF 服务下隐藏了一个。

然后立即生效!那正在融化我的大脑


r
roylac

如果您有类似的路线

[Route("nuclearreactors/{reactorId}")]

您需要在方法中使用完全相同的参数名称,例如

public ReactorModel GetReactor(reactorId)
{
 ...
}

如果您没有传递完全相同的参数,您可能会收到错误“405 method not allowed”,因为路由将与请求不匹配,并且 WebApi 将使用不同的允许 HTTP 方法访问不同的控制器方法。


这也不是答案!
@Div "405 method not allowed" 可以在我分享的情况下显示,因为该方法不会捕获 api-call,因为路由设置无效。然后,api 调用可能会遇到另一个意外的方法,该方法可能允许不同的 HTTP 操作。是的,我同意这个答案可能不是 100% 与实际问题相关,但是 Xardas 的问题标题不是很具体,我相信很多人登陆这里以寻找标题所述问题的答案可能发现这个答案很有用。
P
Per Stolpe

这不能回答您的具体问题,但是当我遇到同样的问题时,我最终来到了这里,我认为更多的人可能会这样做。

我遇到的问题是我无意中将我的 Get 方法声明为静态的。我错过了整个上午,它没有引起属性或类似的警告。

不正确:

public class EchoController : ApiController
{
    public static string Get()
    {
        return string.Empty;
    }
}

正确的:

public class EchoController : ApiController
{
    public string Get()
    {
        return string.Empty;
    }
}

s
shA.t

这是一种解决方案:

<handlers accessPolicy="Read, Script">
   <remove name="WebDAV" />
</handlers>

docs.microsoft.com solution article

并从模块中删除 WebDAV

<remove name="WebDAVModule" />

u
user3963793

[HttpPost] 是不必要的!

[Route("")]
public void Post(ProductModel data)
{
    ...
}

是的,您这样做的方式是正确的,因为您不需要明确的 [HttpPost] ,但是有些人不遵守约定(yikes),因此类似于 [Route("MyMethodSaver"] public string MyMethodtoSave(int? id) --> 需要一个 [HttpPost] 然后它才能工作
S
Spencer Sullivan

我无法解决这个问题。只要 POST 返回 void (ASP.NET 4.0 - WEBAPI 1),我就启用了 CORS 并工作。当我尝试返回 HttpResponseMessage 时,我开始收到 HTTP 405 响应。

根据上述 Llad 的回复,我查看了自己的参考资料。

我的 POST 方法上方列出了属性 [System.Web.Mvc.HttpPost]。

我将其更改为使用:

[System.Web.Http.HttpPostAttribute]
[HttpOptions]
public HttpResponseMessage Post(object json)        
{
    ...
    return new HttpResponseMessage { StatusCode = HttpStatusCode.OK };
}

这解决了我的困境。我希望这对其他人有帮助。

为了完整起见,我的 web.config 中有以下内容:

<httpProtocol>
    <customHeaders>
        <clear />
        <add name="Access-Control-Expose-Headers " value="WWW-Authenticate"/>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, PATCH, DELETE" />
        <add name="Access-Control-Allow-Headers" value="accept, authorization, Content-Type" />
        <remove name="X-Powered-By" />
    </customHeaders>
</httpProtocol>

这将在 OPTIONS 飞行前请求(以及 POST)上调用该方法,此时 json 可能是 null,因为飞行前请求通常没有有效负载,否则您将运行发布操作两次。
P
Panos Roditakis

在我的情况下,我在项目中有一个与 WebAPI 路由(例如沙箱)同名的物理文件夹,并且只有 POST 请求被 IIS 中的静态文件处理程序拦截(显然)。

得到一个误导性的 405 错误而不是更预期的 404,是我花了很长时间进行故障排除的原因。

不容易陷入这种情况,但有可能。希望它可以帮助某人。


R
Ram

确保您的控制器继承自 Controller 类。

即使没有它,东西也能在本地工作,这甚至可能更疯狂。


A
Alexandre Daubricourt

就我而言,我的 POST 处理程序是这种形式:

[HttpPost("{routeParam}")]
public async Task<ActionResult> PostActuality ([FromRoute] int routeParam, [FromBody] PostData data)

我发现我必须交换参数,也就是说首先是正文数据,然后是路由参数,如下所示:

[HttpPost("{routeParam}")]
public async Task<ActionResult> PostActuality ([FromBody] PostData data, [FromRoute] int routeParam)

n
netotz

老问题,但没有一个答案对我有用。

This article 通过在 web.config 中添加以下行解决了我的问题:

<system.webServer>
  <modules runAllManagedModulesForAllRequests="false">
    <remove name="WebDAVModule" />
  </modules>
</system.webServer>

好吧...我这样做了,对我来说它从 405 变为 500 .. 嗯
与@Danushka 建议的类似,我也必须将其放入 <handlers> 因此,除了上述内容之外,在处理程序中添加:<remove name="WebDAV" />
A
Ankit

签入您的项目 .csproj 文件并更改

<IISUrl>http://localhost:PORT/</IISUrl>

像这样到您的网站网址

<IISUrl>http://example.com:applicationName/</IISUrl>

E
Eadel

导致相同行为的另一个可能问题是路由中的默认参数。在我的情况下,控制器已正确定位并实例化,但由于指定了默认 Get 操作,POST 被阻止:

config.Routes.MapHttpRoute(
    name: "GetAllRoute",
    routeTemplate: "api/{controller}.{ext}"/*,
    defaults: new { action = "Get" }*/ // this was causing the issue
);

G
Gonzo345

我遇到了完全相同的问题。我看了两个小时没有运气的问题,直到我意识到我的 POST 方法是 private 而不是 public

有趣的是,现在看到该错误消息有点通用。希望能帮助到你!


Z
Zze

我们有一个类似的问题。我们试图从:

[RoutePrefix("api/car")]
public class CarController: ApiController{

    [HTTPGet]
    [Route("")]
    public virtual async Task<ActionResult> GetAll(){

    }

}

所以我们会.GET("/api/car"),这会抛出一个405 error

修复:

CarController.cs 文件位于目录 /api/car 中,因此当我们请求此 api 端点时,IIS 会发回一个错误,因为看起来我们正在尝试访问我们不允许访问的虚拟目录。

选项 1:更改/重命名控制器所在的目录 选项 2:将路由前缀更改为与虚拟目录不匹配的内容。


g
gkhantaskin

函数名称有时会使 c# 变得复杂。更改函数的名称,它将起作用。像 ProductPut 而不是 PutProduct 或 Put。

public Product ProductPut(Product p)
{
    return repository.Add(p);
}

B
BitQuestions

就我而言,405 错误只出现在生产服务器上,而不是我的开发机器上。

我发现问题是由于我只是“手动”将本地发布的文件夹的内容从本地机器传输到在线生产服务器。

所以,对我来说,修复是简单地删除产品服务器上的所有在线文件,然后使用 Visual Studio 上的“发布”选项通过 FTP 直接从我的本地计算机发布到产品服务器。

我不知道为什么这会改变一些东西,因为在我看来文件是一样的,但是这个东西解决了这个问题,我希望它也可以帮助其他人。