405 метод не разрешен web api

Эта ошибка очень распространена, и я пробовал все решения и не работал. Я отключил публикацию WebDAV на панели управления и добавил ее в свой файл веб-конфигурации:

  <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

Любые предложения?

Ответ 1

Вы отправляете сообщение от клиента:

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

not PUTing.

Ваш метод Web API принимает только запросы PUT.

Итак:

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

Ответ 2

У меня было то же исключение. Моя проблема заключалась в том, что я использовал:

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

Ответ 3

Я пробовал много вещей, чтобы получить метод 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);
    }

Ответ 4

Моя проблема оказалась маршрутизируемой атрибутом в WebAPI. Я создал настраиваемый маршрут, и он рассматривал его как GET вместо WebAPI, обнаружив, что это POST

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

Я знал, что это должно быть что-то глупое (это поглощает весь ваш день)

Ответ 5

Chrome часто пытается выполнить вызов OPTIONS перед выполнением сообщения. Он делает это, чтобы убедиться, что заголовки CORS в порядке. Это может быть проблематично, если вы не обрабатываете вызов OPTIONS в вашем контроллере API.

public void Options() { }

Ответ 6

Эта ошибка также может возникнуть при попытке подключиться к http, когда сервер находится на https.

Это немного сбивало с толку, потому что мои get-запросы были в порядке, проблема присутствовала только с post-запросами.

Ответ 7

Я получал 405 на моем вызове GET, и проблема оказалась в том, что я назвал параметр в методе GET на стороне сервера Get(int formId), и мне нужно было изменить маршрут или переименовать его Get(int id).

Ответ 8

Вы также можете получить ошибку 405, если заявите, что ваш метод ожидает параметра, и вы его не передаете.

Это НЕ работает (ошибка 405)

HTML-представление/Javascript

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

Web Api:

public HttpResponseMessage GetNews(int id)

Таким образом, если сигнатура метода похожа на приведенную выше, вы должны сделать:

HTML-представление/Javascript

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

Ответ 9

Если у вас есть маршрут, например

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

Вам нужно использовать точное имя параметра в методе, например.

public ReactorModel GetReactor(reactorId)
{
 ...
}

Если вы не передадите тот же самый параметр, вы можете получить ошибку "405 метод не разрешен", потому что маршрут не будет соответствовать запросу, а WebApi ударит по другому методу контроллера с другим допустимым HTTP-методом.

Ответ 10

Вот одно решение

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

docs.microsoft.com статья о решении

и удалите WebDAV из модулей

<remove name="WebDAVModule"/>

Ответ 11

Я опаздываю на эту вечеринку, но поскольку ничто выше не было жизнеспособным или не работало в большинстве случаев, вот как это было окончательно разрешено для меня.

На сервере, на котором размещался сайт/служба, была необходима функция! HTTP ACTIVATION!!!

Диспетчер серверов > Управление > Добавить роли и функции > следующий следующий следующий, пока вы не перейдете к функциям > В .NET(каждая версия) отметьте HTTP-активацию. Также обратите внимание, что есть один скрытый под > net > WCF Services.

Теперь это сработало! Это таял мой мозг.

Ответ 12

Это не отвечает на ваш конкретный вопрос, но когда у меня была та же проблема, я оказался здесь, и я подумал, что больше людей могут сделать то же самое.

Проблема, которая у меня была, заключалась в том, что я неизменно объявлял мой метод Get как статический. Я пропустил это на весь передний план, и это не вызвало никаких предупреждений об атрибутах или подобных.

Неправильно:

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

Правильно:

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

Ответ 13

[HttpPost] не требуется!

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

Ответ 14

Я не мог решить этого. Я включил CORS и работал до тех пор, пока POST вернул void (ASP.NET 4.0 - WEBAPI 1). Когда я попытался вернуть HttpResponseMessage, я начал получать ответ HTTP 405.

Основываясь на вышеприведенном Llad-ответе, я взглянул на свои собственные ссылки.

У меня был атрибут [System.Web.Mvc.HttpPost], указанный выше мой метод POST.

Я изменил это, чтобы использовать:

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

Ответ 15

У нас была похожая проблема. Мы пытались получить от:

[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: измените префикс маршрута, чтобы он не совпадал с виртуальным каталогом.

Ответ 16

проверьте файл проекта .csproj и измените

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

на ваш сайт url like this

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

Ответ 17

Другая возможная проблема, вызывающая такое же поведение, - это параметры по умолчанию в маршрутизации. В моем случае контроллер был локализован и инстанцирован правильно, но POST был заблокирован из-за установленного значения по умолчанию Get:

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

Ответ 18

У меня была точно такая же проблема. Два часа я смотрел, что было не так, без удачи, пока не понял, что мой метод POST был private а не public.

Забавно теперь, когда я вижу это сообщение об ошибке. Надеюсь, поможет!

Ответ 19

В моем случае в проекте была физическая папка с тем же именем, что и маршрут WebAPI (например, песочница), и обработчик статических файлов в IIS перехватил только запрос POST (очевидно).

Появление вводящей в заблуждение ошибки 405 вместо более ожидаемой 404 было причиной, по которой мне потребовалось много времени для устранения неполадок.

Не легко впасть в это, но возможно. Надеюсь, это кому-нибудь поможет.

Ответ 20

Убедитесь, что ваш контроллер наследуется от класса Controller.

Это может быть даже более безумно, что вещи будут работать локально, даже без этого.