405方法不允许Web API

本文关键字:API Web 不允许 方法 | 更新日期: 2023-09-27 18:06:41

这个错误很常见,我尝试了所有的解决方案,但都不起作用。我在控制面板中禁用了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

有什么建议吗?

405方法不允许Web API

您正在从客户端发送:

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

不加点。

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

:

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

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

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";
}

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

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

我知道它必须是愚蠢的东西(消耗你的一整天)

我尝试了很多事情让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);
    }

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

这有点令人困惑,因为我的get-request是OK的,问题只出现在post-request。

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

public void Options() { }

我迟到了,但在大多数情况下,以上都不可行或不起作用,以下是我最终解决的方法。

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

服务器管理器>管理>添加角色和功能>下一个下一个直到你得到功能>下。net(每个版本)勾选HTTP激活。还要注意,在>net> WCF Services下面隐藏了一个。

这立即起作用了!这是融化我的大脑

你也可以得到405错误,如果说你的方法是期待一个参数,你没有传递它。

This does NOT work (405 error)

HTML视图/Javascript

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

Web Api:

public HttpResponseMessage GetNews(int id)

因此,如果方法签名像上面那样,那么你必须这样做:

HTML视图/Javascript

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

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

如果您有像

这样的路由
[Route("nuclearreactors/{reactorId}")]

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

public ReactorModel GetReactor(reactorId)
{
 ...
}

如果你没有传递完全相同的参数,你可能会得到错误"405方法不允许",因为路由将不匹配请求和WebApi将击中不同的控制器方法与不同的允许的HTTP方法。

老问题,但没有一个答案适合我。

本文通过向web.config添加以下行来解决我的问题:

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

这并没有回答你的具体问题,但是当我遇到同样的问题时,我在这里结束了,我想更多的人可能会做同样的事情。

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

不正确:

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

正确的:

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

这里有一个解决方案:

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

learn.microsoft.com解决方案文章

和从模块中删除WebDAV

<remove name="WebDAVModule" />

[HttpPost]是不必要的!

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

我无法解决这个问题。我启用了CORS,只要POST返回void (ASP. js)就可以工作。当我试图返回一个HttpResponseMessage时,我开始得到HTTP 405响应。

根据上面Llad的回答,我看了看我自己的参考资料。

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

我将其改为:

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

这解决了我的悲伤。我希望这能帮助到其他人。

为了完整起见,我在我的web中有以下内容。配置:

<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>

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

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

不容易陷入这种情况,但可能。希望能帮到别人。

确保你的控制器继承自Controller

更疯狂的是,即使没有它,东西也能在本地工作。

我的POST处理程序是这样的:

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

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

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

检查您的项目.csproj文件并更改

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

到你的网站url,像这样

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

另一个可能导致相同行为的问题是路由中的默认参数。在我的例子中,控制器被正确地定位和实例化,但是POST被阻塞了,因为默认的Get动作指定:

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

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

现在看到错误消息是一种通用的有趣。希望能有所帮助!

我们也遇到了类似的问题。我们试图从:

获取
[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: change/rename控制器所在目录
选项2:将路由前缀更改为与虚拟目录不匹配的前缀。

在我的例子中,405错误只出现在生产服务器上,而没有出现在开发机器上。

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

所以,对我来说,解决办法是简单地删除prod服务器上的所有在线文件,然后使用"发布"命令。选项,直接从我的本地机器通过FTP发布到prod服务器。

我不知道为什么这改变了一些东西,因为它似乎对我的文件是一样的,但这个东西解决了问题,我希望它可以帮助别人了。

另一个可能的原因可能与IIS中的会话状态配置有关,导致重定向附加" AspxAutoDetectCookieSupport=1"到URL。在我的情况下,我正在执行POST,但重定向是由HttpClient作为GET执行的。

我找到的解决方案是在我的web.config中添加以下内容:

<system.web>
   <sessionState cookieless="UseCookies" />
</system.web>

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

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