[英]405 method not allowed Web API
这个错误很常见,我尝试了所有的解决方案,但没有一个有效。 我在控制面板中禁用了 WebDAV 发布并将其添加到我的 web 配置文件中:
<handlers>
<remove name="WebDAV"/>
</handlers>
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDAVModule"/>
</modules>
错误仍然存在。 这是 controller:
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
有什么建议么?
您正在从客户端发布:
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";
}
我尝试了很多方法来让 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);
}
我的问题原来是 WebAPI 中的属性路由。 我创建了一个自定义路由,它把它当作一个 GET 而不是 WebAPI 发现它是一个 POST
[Route("")]
[HttpPost] //I added this attribute explicitly, and it worked
public void Post(ProductModel data)
{
...
}
我知道它一定是愚蠢的(消耗你一整天的时间)
Chrome 经常会在发布帖子之前尝试进行OPTIONS
调用。 这样做是为了确保 CORS 标头是有序的。 如果您没有在 API 控制器中处理OPTIONS
调用,则可能会出现问题。
public void Options() { }
当服务器在 https 上时尝试连接到 http 时,也会发生此错误。
这有点令人困惑,因为我的 get-requests 没问题,问题只出现在 post-requests 中。
我在 GET 调用中得到 405,问题是我在 GET 服务器端方法Get(int formId)
命名了参数,我需要更改路由,或将其重命名为Get(int id)
。
如果说您的方法需要一个参数而您没有传递它,您也可能会收到 405 错误。
这不起作用(405错误)
HTML 视图/Javascript
$.ajax({
url: '/api/News',
//.....
网络API:
public HttpResponseMessage GetNews(int id)
因此,如果方法签名与上述类似,那么您必须执行以下操作:
HTML 视图/Javascript
$.ajax({
url: '/api/News/5',
//.....
我参加这个聚会迟到了,但由于以上内容在大多数情况下都不可行或有效,以下是我最终解决的方法。
在托管站点/服务的服务器上,需要一个功能! HTTP 激活!!!
服务器管理器 > 管理 > 添加角色和功能 > next next next 直到你到达 Features > Under .NET (每个版本) 勾选 HTTP Activation。 另请注意,在 >net > WCF Services 下隐藏了一个。
然后立即生效! 那融化了我的大脑
如果你有这样的路线
[Route("nuclearreactors/{reactorId}")]
您需要在方法中使用完全相同的参数名称,例如
public ReactorModel GetReactor(reactorId)
{
...
}
如果您不传递完全相同的参数,您可能会收到错误“405 method not allowed”,因为路由将与请求不匹配,并且 WebApi 将使用不同的允许 HTTP 方法访问不同的控制器方法。
这并不能回答你的具体问题,但是当我遇到同样的问题时,我最终来到这里,我认为更多的人可能会做同样的事情。
我遇到的问题是我无意中将 Get 方法声明为static 。 我错过了整个上午,它没有引起属性或类似的警告。
不正确:
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>
并从模块中删除 WebDAV
<remove name="WebDAVModule" />
[HttpPost] 不需要!
[Route("")]
public void Post(ProductModel data)
{
...
}
我无法解决这个问题。 只要 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>
在我的情况下,我在项目中有一个与 WebAPI 路由(例如沙箱)同名的物理文件夹,并且只有 POST 请求被 IIS 中的静态文件处理程序拦截(显然)。
得到一个误导性的 405 错误而不是更预期的 404,是我花了很长时间进行故障排除的原因。
不容易陷入这种境地,但有可能。 希望它可以帮助某人。
就我而言,我的 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)
签入您的项目 .csproj 文件并更改
<IISUrl>http://localhost:PORT/</IISUrl>
像这样到您的网站网址
<IISUrl>http://example.com:applicationName/</IISUrl>
导致相同行为的另一个可能问题是路由中的默认参数。 在我的情况下,控制器被正确定位和实例化,但由于指定了默认的Get
操作,POST 被阻止:
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:更改/重命名控制器所在的目录
选项 2:将路由前缀更改为与虚拟目录不匹配的内容。
确保您的控制器继承自Controller
类。
即使没有它,东西也能在本地工作,这甚至可能更疯狂。
老问题,但没有一个答案对我有用。
本文通过向web.config
添加以下行解决了我的问题:
<system.webServer>
<modules runAllManagedModulesForAllRequests="false">
<remove name="WebDAVModule" />
</modules>
</system.webServer>
函数名称有时会使 c# 变得复杂。 更改函数的名称,它将起作用。 像 ProductPut 而不是 PutProduct 或 Put。
public Product ProductPut(Product p)
{
return repository.Add(p);
}
就我而言,405 错误仅出现在生产服务器中,而不出现在我的开发机器上。
我发现问题是由于我只是“手动”将本地发布文件夹的内容从本地机器传输到在线生产服务器。
因此,对我来说,修复方法是简单地删除 prod 服务器上的所有在线文件,然后使用 Visual Studio 上的“发布”选项通过 FTP 从我的本地机器直接发布到 prod 服务器。
我不知道为什么这会改变一些东西,因为在我看来文件是相同的,但是这件事解决了问题,我希望它也能帮助其他人。
Another possible cause can be to do with Session State config in IIS causing a redirect which appends "?AspxAutoDetectCookieSupport=1" to the URL. 在我的情况下,我正在执行 POST,但重定向是由 HttpClient 作为 GET 执行的。
我找到的解决方案是将以下内容添加到我的 web.config 中:
<system.web>
<sessionState cookieless="UseCookies" />
</system.web>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.