Esse erro é muito comum, tentei todas as soluções e nenhuma funcionou. Desativei a publicação de WebDAV no painel de controle e adicionei isso ao meu arquivo de configuração da web:
<handlers>
<remove name="WebDAV"/>
</handlers>
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDAVModule"/>
</modules>
O erro ainda persiste. Este é o controlador:
static readonly IProductRepository repository = new ProductRepository();
public Product Put(Product p)
{
return repository.Add(p);
}
Implementação do método:
public Product Add(Product item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
item.Id = _nextId++;
products.Add(item);
return item;
}
E é aqui que a exceção é lançada:
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
Alguma sugestão?
c#
asp.net-web-api
webdav
Xardas
fonte
fonte
Eu tive a mesma exceção. Meu problema era que eu tinha usado:
using System.Web.Mvc; // Wrong namespace for HttpGet attribute !!!!!!!!! [HttpGet] public string Blah() { return "blah"; }
DEVERIA ESTAR
using System.Web.Http; // Correct namespace for HttpGet attribute !!!!!!!!! [HttpGet] public string Blah() { return "blah"; }
fonte
Eu tentei várias coisas para fazer o método DELETE funcionar (eu estava obtendo o método 405 não permitido na API da web) e, finalmente, adicionei [Route ("api / scan / {id}")] ao meu controlador e funcionou bem. espero que este post ajude alguém.
// 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); }
fonte
Meu problema acabou sendo o Roteamento de Atributos na WebAPI. Eu criei uma rota personalizada e a tratou como um GET em vez de WebAPI, descobrindo que era um POST
[Route("")] [HttpPost] //I added this attribute explicitly, and it worked public void Post(ProductModel data) { ... }
Eu sabia que tinha que ser algo bobo (que consome o dia inteiro)
fonte
O Chrome frequentemente tenta fazer uma
OPTIONS
chamada antes de fazer uma postagem. Ele faz isso para garantir que os cabeçalhos CORS estejam em ordem. Pode ser problemático se você não estiver lidando com aOPTIONS
chamada em seu controlador de API.public void Options() { }
fonte
Este erro também pode ocorrer quando você tenta se conectar a http enquanto o servidor está em https.
Foi um pouco confuso porque minhas solicitações de obtenção estavam OK, o problema estava presente apenas com solicitações posteriores.
fonte
Eu estava recebendo o 405 em minha chamada GET, e o problema acabou que eu nomeei o parâmetro no método do lado do servidor GET
Get(int formId)
e precisei alterar a rota ou renomeá-laGet(int id)
.fonte
Você também pode obter o erro 405 se disser que seu método está esperando um parâmetro e você não o está passando.
Isso NÃO funciona (erro 405)
Visualização HTML / Javascript
$.ajax({ url: '/api/News', //.....
Web Api:
public HttpResponseMessage GetNews(int id)
Portanto, se a assinatura do método for como a acima, você deve fazer:
Visualização HTML / Javascript
$.ajax({ url: '/api/News/5', //.....
fonte
Estou atrasado para esta festa, mas como nada acima era viável ou funcionava na maioria dos casos, aqui está como isso foi finalmente resolvido para mim.
No servidor em que o site / serviço estava hospedado, um recurso era necessário! ATIVAÇÃO HTTP !!!
Isso funcionou instantaneamente! Isso estava derretendo meu cérebro
fonte
Se você tem uma rota como
[Route("nuclearreactors/{reactorId}")]
Você precisa usar exatamente o mesmo nome de parâmetro no método, por exemplo
public ReactorModel GetReactor(reactorId) { ... }
Se você não passar exatamente o mesmo parâmetro, poderá obter o erro "método 405 não permitido" porque a rota não corresponderá à solicitação e o WebApi atingirá um método controlador diferente com método HTTP permitido diferente.
fonte
Isso não responde à sua pergunta específica, mas quando tive o mesmo problema, acabei aqui e imaginei que mais pessoas poderiam fazer o mesmo.
O problema que eu tive foi que eu tinha declarado indeliberadamente meu método Get como estático . Perdi isso durante toda a manhã e não causou avisos de atributos ou similares.
Incorreta:
public class EchoController : ApiController { public static string Get() { return string.Empty; } }
Corrigir:
public class EchoController : ApiController { public string Get() { return string.Empty; } }
fonte
Aqui está uma solução
<handlers accessPolicy="Read, Script"> <remove name="WebDAV" /> </handlers>
artigo de solução docs.microsoft.com
e remover WebDAV dos módulos
<remove name="WebDAVModule" />
fonte
[HttpPost] é desnecessário!
[Route("")] public void Post(ProductModel data) { ... }
fonte
Eu NÃO consegui resolver isso. Eu estava com o CORS habilitado e funcionando desde que o POST retornasse vazio (ASP.NET 4.0 - WEBAPI 1). Quando tentei retornar um HttpResponseMessage, comecei a obter a resposta HTTP 405.
Com base na resposta de Llad acima, dei uma olhada em minhas próprias referências.
Eu tinha o atributo [System.Web.Mvc.HttpPost] listado acima do meu método POST.
Eu mudei isso para usar:
[System.Web.Http.HttpPostAttribute] [HttpOptions] public HttpResponseMessage Post(object json) { ... return new HttpResponseMessage { StatusCode = HttpStatusCode.OK }; }
Isso resolveu meus problemas. Espero que isto ajude alguém.
Para fins de integridade, eu tinha o seguinte em meu 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>
fonte
json
é provável,null
uma vez que as solicitações pré-voo geralmente não têm cargas úteis, ou você executará a ação pós duas vezes.Tivemos um problema semelhante. Estávamos tentando OBTER de:
[RoutePrefix("api/car")] public class CarController: ApiController{ [HTTPGet] [Route("")] public virtual async Task<ActionResult> GetAll(){ } }
Então nós faríamos
.GET("/api/car")
e isso geraria um405 error
.O conserto:
O
CarController.cs
arquivo estava no diretório/api/car
portanto, quando solicitávamos esse endpoint da API, o IIS retornava um erro porque parecia que estávamos tentando acessar um diretório virtual para o qual não tínhamos permissão.Opção 1: alterar / renomear o diretório em que o controlador está.
Opção 2: alterar o prefixo da rota para algo que não corresponda ao diretório virtual.
fonte
No meu caso, eu tinha uma pasta física no projeto com o mesmo nome da rota WebAPI (ex. Sandbox) e apenas a solicitação POST foi interceptada pelo manipulador de arquivos estáticos no IIS (obviamente).
Receber um erro 405 enganoso em vez do 404 mais esperado, foi o motivo pelo qual demorei para solucionar o problema.
Não é fácil cair nisso, mas é possível. Espero que ajude alguém.
fonte
De minha parte, meu gerenciador de POST tinha a seguinte forma:
[HttpPost("{routeParam}")] public async Task<ActionResult> PostActuality ([FromRoute] int routeParam, [FromBody] PostData data)
Descobri que precisava trocar os argumentos , ou seja, os dados do corpo primeiro, depois o parâmetro da rota, como este:
[HttpPost("{routeParam}")] public async Task<ActionResult> PostActuality ([FromBody] PostData data, [FromRoute] int routeParam)
fonte
verifique o arquivo .csproj do projeto e altere
<IISUrl>http://localhost:PORT/</IISUrl>
para o url do seu site assim
<IISUrl>http://example.com:applicationName/</IISUrl>
fonte
Outro possível problema que causa o mesmo comportamento são os parâmetros padrão no roteamento. No meu caso, o controlador foi localizado e instanciado corretamente, mas o POST foi bloqueado devido à
Get
ação padrão especificada:config.Routes.MapHttpRoute( name: "GetAllRoute", routeTemplate: "api/{controller}.{ext}"/*, defaults: new { action = "Get" }*/ // this was causing the issue );
fonte
Eu estava tendo exatamente o mesmo problema. Procurei por duas horas o que estava errado sem sorte até perceber que meu
POST
método era oprivate
contráriopublic
.Engraçado agora ver que a mensagem de erro é genérica. Espero que ajude!
fonte
Certifique-se de que seu controlador herda da
Controller
classe.Pode até ser mais louco que as coisas funcionem localmente, mesmo sem isso.
fonte