405方法不允许使用web api

时间:2013-03-30 12:53:45

标签: c# asp.net-web-api webdav

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

有什么建议吗?

24 个答案:

答案 0 :(得分:57)

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

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

答案 1 :(得分:51)

您正在从客户端发帖:

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

不是PUTing。

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

所以:

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

答案 2 :(得分:17)

我试了很多东西让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);
    }

答案 3 :(得分:10)

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

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

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

答案 4 :(得分:4)

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

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

答案 5 :(得分:4)

这是一个解决方案

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

docs.microsoft.com solution article

并从模块中删除WebDAV

<remove name="WebDAVModule" />

答案 6 :(得分:4)

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

答案 7 :(得分:4)

Chrome经常会在发帖前尝试拨打OPTIONS电话。这样做是为了确保CORS标头按顺序排列。如果您未在API控制器中处理OPTIONS调用,则可能会出现问题。

public void Options() { }

答案 8 :(得分:4)

如果你的方法期望参数而你没有传递参数,你也可以得到405错误。

这不起作用(405错误)

HTML查看/ Javascript

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

Web Api:

public HttpResponseMessage GetNews(int id)

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

HTML查看/ Javascript

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

答案 9 :(得分:4)

如果你有像

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

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

public ReactorModel GetReactor(reactorId)
{
 ...
}

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

答案 10 :(得分:3)

我参加这个聚会的时间比较晚,但由于上述任何事情都不可行或在大多数情况下都有效,以下是我最终解决这个问题的方法。

在托管网站/服务的服务器上,需要一项功能! HTTP ACTIVATION !!!

  

服务器管理器&gt;管理&gt;添加角色和功能&gt;下一个接下来,直到你到达功能&gt;在.NET(每个版本)下勾选HTTP激活。   另请注意,有一个隐藏在&gt; net&gt;下WCF服务。

然后立即工作! 这让我的脑子融化了

答案 11 :(得分:2)

这不能回答你的具体问题,但当我遇到同样的问题时,我最终会在这里结束,并且我认为更多的人可能会这样做。

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

不正确:

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

正确:

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

答案 12 :(得分:2)

我无法解决这个问题。只要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>

答案 13 :(得分:2)

[HttpPost]是不必要的!

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

答案 14 :(得分:0)

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

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

答案 15 :(得分:0)

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

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

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

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

答案 16 :(得分:0)

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

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

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

答案 17 :(得分:0)

就我而言,我的POST处理程序具有以下形式:

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

我发现我必须交换参数,也就是说,首先是主体数据,然后是route参数,

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

答案 18 :(得分:0)

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

甚至没有这些东西,甚至可以在本地工作甚至更疯狂。

答案 19 :(得分:0)

就我而言,我在项目中有一个物理文件夹,名称与WebAPI路由相同(例如,沙箱),并且IIS中的静态文件处理程序仅拦截了POST请求(显然)。

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

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

答案 20 :(得分:0)

我们遇到了类似的问题。我们正在尝试从以下位置获取信息:

[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:将路由前缀更改为与虚拟目录不匹配的内容。

答案 21 :(得分:0)

我遇到了完全相同的问题。我花了两个小时的时间才发现运气不好,直到意识到我的POST方法是private而不是public

现在很有趣,看到错误消息有点普通。希望对您有帮助!

答案 22 :(得分:0)

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

Get

答案 23 :(得分:0)

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

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

到你的网站这样的网址

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