Метод 405 не дозволений веб-API


89

Ця помилка є дуже поширеною, і я спробував усі рішення, і жодне з них не працювало. Я вимкнув публікацію 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

Будь-які пропозиції?

Відповіді:


61

Ви розміщуєте повідомлення від клієнта:

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

не кладе.

Ваш метод веб-API приймає лише запити PUT.

Тому:

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

Помилка 'HttpClient' не містить визначення для 'PostAsJsonAsync' під час спроби ввести код.
agileDev

61

У мене був такий самий виняток. Моя проблема полягала в тому, що я використовував:

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

18

Я спробував багато чого, щоб змусити роботу методу DELETE (я отримував метод 405, заборонений веб-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);
    }

Чомусь моє, це лише не працювало для видалення, для створення та оновлення воно працювало нормально. Ну, я щойно додав [HttpPost], і це спрацювало. Але дякую, ви
вивели

1
Чому ви просто не додаєте атрибут [HttpDelete]?
johnny 5

14

Моєю проблемою виявилася маршрутизація атрибутів у WebAPI. Я створив власний маршрут, і він розглядав його як GET замість WebAPI, виявляючи, що це POST

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

Я знав, що це має бути щось дурне (що поглинає весь твій день)


Це врятувало мій день!
Phate01,

6

Chrome часто намагається OPTIONSзателефонувати, перш ніж робити публікацію. Це робить це, щоб переконатись, що заголовки CORS в порядку. Це може бути проблематично, якщо ви не обробляєте OPTIONSвиклик у своєму контролері API.

public void Options() { }

6

Ця помилка може також виникнути під час спроби підключитися до http, коли сервер працює на https.

Це було трохи заплутаним, оскільки мої запити на отримання були в порядку, проблема була присутня лише у пост-запитах.


4

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


4

Ви також можете отримати помилку 405, якщо скажете, що ваш метод очікує параметра, а ви не передаєте його.

Це НЕ працює (помилка 405)

Перегляд HTML / Javascript

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

Web Api:

public HttpResponseMessage GetNews(int id)

Таким чином, якщо підпис методу схожий на наведений вище, ви повинні зробити:

Перегляд HTML / Javascript

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

Здається, я стикаюся з помилками 405 з різних причин, всі вони зводяться до того, що він намагається ВДАРИТИ підпис методу та проблему параметра, або проблему іменування конвенції, або проблему атрибута тощо ...
Том Стікель,

4

Я запізнююсь до цієї вечірки, але оскільки нічого вище не було життєздатним чи працюючим у більшості випадків, ось як це нарешті було вирішено для мене.

На сервері, на якому розміщувався сайт / послуга, потрібна особливість! АКТИВАЦІЯ HTTP !!!

Менеджер серверів> Керування> Додавання ролей та функцій> наступний наступний наступний, поки не дійдете до Функції> У розділі .NET (кожна версія) поставте галочку Активація HTTP. Також зауважте, що під> net> WCF Services є одна прихована.

Потім це спрацювало миттєво! Це плавило мій мозок


4

Якщо у вас є такий маршрут

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

Вам потрібно використовувати саме те саме ім'я параметра в методі, наприклад

public ReactorModel GetReactor(reactorId)
{
 ...
}

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


Це теж не відповідь!
Divyang Desai

@Div "Метод 405 не дозволений" може бути показаний у випадку, коли я поділився, оскільки метод не вловлює api-виклик, оскільки налаштування маршруту є недійсним. Тоді виклик api може потрапити до іншого ненавмисного методу, який може мати іншу дозволену дію HTTP. Так, я погоджуюсь, що ця відповідь не може бути на 100% релевантною для фактичного питання, однак назва питання від Xardas не дуже конкретна, і я вважаю, що багато людей, які приземляються тут у пошуках відповідей на питання, як зазначено в назві, можуть вважають цю відповідь корисною.
roylac


3

Це не відповідає на ваше конкретне запитання, але коли у мене була та сама проблема, я опинився тут і зрозумів, що більше людей може зробити те саме.

Проблема у мене полягала в тому, що я ненавмисно оголосив свій метод Get статичним . Я пропустив це цілий полудень, і це не викликало жодних попереджень від атрибутів чи подібних.

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

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

Правильно:

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

2

[HttpPost] непотрібний!

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

1
Так, ви робите це правильно, оскільки вам не потрібен явний [HttpPost], проте є деякі люди, які не дотримуються домовленостей (yikes) і, отже, щось на зразок [Route ("MyMethodSaver"] відкритий рядок MyMethodtoSave (int? id) -> для чого знадобиться [HttpPost], і тоді він спрацює
Tom Stickel

2

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

Виходячи з відповіді Льода вище, я подивився власні посилання.

У мене був атрибут [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>

Цей метод матиме виклик перед запитом на запит OPTIONS (а також на POST), і тоді jsonце ймовірно, nullоскільки запити перед рейсом, як правило, не мають корисного навантаження, або ви виконаєте дію після публікації двічі.
glennsl

1

У нас була подібна проблема. Ми намагалися ОТРИМАТИ з:

[RoutePrefix("api/car")]
public class CarController: ApiController{

    [HTTPGet]
    [Route("")]
    public virtual async Task<ActionResult> GetAll(){

    }

}

Отже, ми б .GET("/api/car")і це кинули 405 error.


Виправлення:

CarController.csФайл знаходився в каталозі /api/carтому , коли ми були запросивши апі кінцевої точку, IIS буде повертати помилку , тому що здавалося, що ми намагалися отримати доступ до віртуального каталогу , який ми не дозволялися.

Варіант 1: змініть / перейменуйте каталог, в якому знаходиться контролер у
Варіанті 2: змініть префікс маршруту на щось, що не відповідає віртуальному каталогу.


1

У моєму випадку у мене була фізична папка в проекті з тим самим іменем, що і маршрут WebAPI (наприклад, пісочниця), і лише запит POST був перехоплений обробником статичних файлів у IIS (очевидно).

Отримання помилкової помилки 405 замість більш очікуваної 404 - причина, через яку мені знадобилося багато часу для усунення несправностей.

Нелегко впасти в це, але можливо. Сподіваюся, це комусь допомагає.


1

Зі свого боку, мій обробник 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)

0

перевірити файл .csproj вашого проекту та змінити

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

на адресу вашого веб-сайту, як це

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

0

Інша можлива проблема, яка спричиняє таку ж поведінку, - це параметри за замовчуванням у маршрутизації. У моєму випадку контролер знаходився та створював екземпляри правильно, але POST був заблокований через Getвказану дію за замовчуванням :

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

0

У мене була точно така ж проблема. Дві години я дивився на те, що сталося невдало, поки не зрозумів, що замість цього POSTбув метод .privatepublic

Зараз смішно бачити, що повідомлення про помилку є загальним. Сподіваюся, це допоможе!


0

Переконайтеся, що ваш контролер успадковує від Controllerкласу.

Можливо, навіть шаленіше, що речі працювали б локально навіть без цього.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.