ASP.NET Web API - команды PUT & DELETE не разрешены - IIS 8
Я недавно обновил Visual Studio 2010 до Visual Studio 2012 RC. Программа установки также устанавливает IIS 8 Express, который теперь Visual Studio использует в качестве веб-сервера по умолчанию.
IIS 8 блокирует мои запросы веб-API, которые используют глаголы PUT AND DELETE. IIS возвращает ошибку 405, The requested resource does not support http method 'PUT'
,
Я знаю, что у людей были проблемы с этим в прошлом, и есть несколько сообщений об этом в переполнении стека. С IIS 7 Express было решено удалить WebDav. К сожалению, я не вижу способа сделать это с IIS 8.
Я пытался отредактировать разделы WebDav из applicationhost.config, но это не помогло. Например я удалил <add name="WebDAVModule" image="%IIS_BIN%\webdav.dll" />
из файла конфигурации.
Я потратил слишком много времени на это. Должен быть простой способ включить PUT и DELETE?
22 ответа
Хорошо. Я наконец докопался до этого. Вам нужно перепрыгнуть через несколько обручей, чтобы глаголы PUT и DELETE работали правильно с IIS8. Фактически, если вы установите кандидат на выпуск VS 2012 и создадите новый проект WEB API, вы обнаружите, что примеры методов PUT и DELETE возвращают 404 ошибки из коробки.
Чтобы использовать глаголы PUT и DELETE с Web API, вам нужно отредактировать%userprofile%\documents\iisexpress\config\applicationhost.config и добавить глаголы в обработчик ExtensionlessUrl следующим образом:
Измените эту строку:
<add name="ExtensionlessUrl-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
чтобы:
<add name="ExtensionlessUrl-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
В дополнение к вышесказанному вы должны убедиться, что WebDAV не мешает вашим запросам. Это можно сделать, закомментировав следующие строки из applicationhost.config.
<add name="WebDAVModule" image="%IIS_BIN%\webdav.dll" />
<add name="WebDAVModule" />
<add name="WebDAV" path="*" verb="PROPFIND,PROPPATCH,MKCOL,PUT,COPY,DELETE,MOVE,LOCK,UNLOCK" modules="WebDAVModule" resourceType="Unspecified" requireAccess="None" />
Также имейте в виду, что соглашение о веб-API по умолчанию состоит в том, что имя вашего метода должно совпадать с вызванным глаголом HTTP. Например, если вы отправляете HTTP-запрос на удаление, ваш метод по умолчанию должен называться Delete.
Измените файл Web.Config, как показано ниже. Это будет действовать как очарование.
В узле <system.webServer>
добавить ниже часть кода
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDAVModule"/>
</modules>
После добавления ваш Web.Config будет выглядеть ниже
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDAVModule"/>
</modules>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
Удаление WebDAV отлично работает для моего случая:
<modules>
<remove name="WebDAVModule"/>
</modules>
<handlers>
<remove name="WebDAV" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
всегда лучше решить проблему через web.config, а не пытаться исправить ее через iis или machine.config, чтобы не допустить, чтобы это происходило, если бы приложение размещалось на другом компьютере.
Обновите ваш web.config
<system.webServer>
<modules>
<remove name="WebDAVModule"/>
</modules>
<handlers>
<remove name="WebDAV" />
<remove name="ExtensionlessUrl-Integrated-4.0" />
<add name="ExtensionlessUrl-Integrated-4.0"
path="*."
verb="GET,HEAD,POST,DEBUG,DELETE,PUT"
type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
Устраняет необходимость изменять настройки вашего хоста.
В Asp.Net Web API - webconfig. Это работает во всех браузерах.
Добавьте следующий код в тег System.web
<webServices>
<protocols>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
Замените ваш тег system.webserver на приведенный ниже код
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>
</httpProtocol>
<modules runAllManagedModulesForAllRequests="false">
<remove name="WebDAVModule" />
</modules>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
Включить CORS (красиво и аккуратно)
1. добавить пакет CORS Nuget
Install-Package microsoft.aspnet.webapi.cors
2. в файле WebApiConfig.cs для регистрации метода добавьте следующий код:
config.EnableCors();
например:
используя System.Web.Http;
namespace test
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.EnableCors(); //add this**************************
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
3.Добавьте приведенный ниже код в пространство имен контроллера, включите get, post, delete, put или любой http метод
[EnableCors(origins: "The address from which the request comes", headers: "*", methods: "*")]
например:
using System.Web.Http.Cors;//add this******************************
namespace Test.Controllers
{
[EnableCors(origins: "http://localhost:53681/HTML/Restaurant.html", headers: "*", methods: "*")]
public class RestaurantController : ApiController
{
protected TestBusinessLayer DevTestBLL = new TestBusinessLayer();
public List<Restaurant> GET()
{
return DevTestBLL.GetRestaurant();
}
public List<Restaurant> DELETE(int id)
{
return DevTestBLL.DeleteRestaurant(id);
}
}
}
ссылка: http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api
Просто быстрое обновление для всех, кто может столкнуться с этой проблемой. На сегодняшний день изменение%userprofile%\documents\iisexpress\config\applicationhost.config больше не работает (до сих пор это работало нормально, не уверен, что это связано с обновлением Windows). После нескольких часов разочарования я изменил web.config, добавив эти обработчики в system.webserver, чтобы он заработал:
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
Это работало для меня на iis8 вместе с некоторыми другими ответами. Моя ошибка была специально для 404.6
<system.webServer>
<security>
<requestFiltering>
<verbs applyToWebDAV="false">
<add verb="DELETE" allowed="true" />
</verbs>
</requestFiltering>
</security>
</system.webServer>
Для PHP это было просто:
- Откройте IIS
- Перейти к отображению обработчиков
- нажмите изменить на php5.6.x или php7.0.x
- нажмите "запросить ограничения"
- на вкладке глаголов выберите "один из следующих глаголов" и добавьте "GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS"
Я думаю, что это будет работать и с другими обработчиками.
После того, как ничего не получилось, я смог решить эту проблему с помощью следующих шагов:
• Не выбирал настройки IIS "WEB DAV PUBLISHING" во время установки IIS. • INETMGR - веб-сайт по умолчанию - фильтрация запросов - глаголы HTTP - PUT as True
После бесконечного поиска и пробования уже предоставленных ответов (добавление глаголов PUT,DELETE и удаление WEBdav) это просто не сработало.
Я пошел в настройки журналов IIS: > Просмотр файлов журнала. В моем случае W3SVC4 был папкой с самой последней датой, открыл папку, посмотрел последний файл журнала и увидел эту запись: GET /Rejected-By-UrlScan ~/MYDOMAIN/API/ApiName/UpdateMETHOD
Метод обновления был указан с глаголом GET, странно, верно? Так что я гуглил для Rejected-By-UrlScan и нашел эту ссылку: UrlScan Broke My Blog.
Я пошел сюда: %windir%\system32\inetsrv\urlscan\UrlScan.ini
По сути, UrlScan блокирует команды PUT и DELETE. Я открыл этот INI-файл, добавил PUT и DELETE в AllowVerbs и удалил их из списков DenyVerbs. Я сохранил INI-файл, и он работал! Поэтому для меня эти шаги были необходимы рядом с подсказками ExtensionlessUrlHandler.
Windows Webserver 2008 R2 (64-разрядная версия), IIS 7.5. Я использую это в сочетании с DotNetNuke (DNN) WebAPI. ASP.Net 4.0 Мой метод обновления:
[HttpPut]
[DnnAuthorize(StaticRoles = "MyRoleNames")]
public HttpResponseMessage UpdateMETHOD(DTO.MyObject myData)
Я столкнулся с той же проблемой с вами, затем решил ее, вот решения, я хотел бы, может быть, может помочь
Первый
В IIS modules
Конфигурация, зациклите модуль WebDAVModule, если он есть на вашем веб-сервере, затем удалите его
второй
В IIS handler mappings
конфигурации, вы можете увидеть список включения обработчика, чтобы выбрать the PHP item
, отредактируйте его, на странице редактирования нажмите кнопку запроса ограничений, затем выберите the verbs tab
в модальном поле укажите глаголы, которые будут обрабатывать метку, отметьте all verbs radio
, затем нажмите ОК, вы также можете увидеть предупреждение, оно показывает нам, что использовать двойные кавычки для выполнения PHP-CGI, а затем сделать это
если это сделано, то перезапустите сервер IIS, все будет в порядке
Помимо всех вышеуказанных решений, проверьте, есть ли у вас идентификатор или какой-либо другой пользовательский параметр в методе DELETE, совпадающий с конфигурацией маршрута.
public void Delete(int id)
{
//some code here
}
Если вы столкнулись с повторными ошибками 405, лучше сбросьте сигнатуру метода по умолчанию, как описано выше, и попробуйте
Конфигурация маршрута по умолчанию будет искать идентификатор в URL. Таким образом, идентификатор параметра здесь важен, если вы не измените конфигурацию маршрута в папке App_Start.
Вы можете изменить тип данных идентификатора, хотя.
Например, приведенный ниже метод должен работать просто отлично:
public void Delete(string id)
{
//some code here
}
Примечание. Также убедитесь, что вы передаете данные через URL, а не метод данных, который будет содержать полезную нагрузку в качестве основного содержимого.
DELETE http://{url}/{action}/{id}
Пример:
DELETE http://localhost/item/1
Надеюсь, поможет.
я добавил
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="WebDAV" />
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" requireAccess="None"/>
<add name="WebDAV" path="*" verb="PROPFIND,PROPPATCH,MKCOL,PUT,DELETE,COPY,MOVE,LOCK,UNLOCK" modules="WebDAVModule" resourceType="Unspecified" requireAccess="None" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,DELTE" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="0" />
</handlers>
<aspNetCore processPath=".\Informing.Gateway.Api.exe" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="InProcess" />
</system.webServer>
</location>
</configuration>
И это сработало. Вот и все
Я использую файл Ashx в приложении MVC, и ни один из приведенных выше ответов не работает для меня. IIS 10.
Вот что сработало. Вместо изменения "ExtensionlessUrl-Integrated-4.0" в IIS или web.config я изменил "SimpleHandlerFactory-Integrated-4.0" для файлов "*.ashx":
<add name="SimpleHandlerFactory-Integrated-4.0" path="*.ashx"
verb="GET,HEAD,POST,DEBUG,PUT,DELETE"
type="System.Web.UI.SimpleHandlerFactory"
resourceType="Unspecified" requireAccess="Script"
preCondition="integratedMode,runtimeVersionv4.0" />
Вот как можно разрешить дополнительные HTTP-глаголы с помощью графического интерфейса IIS Manager.
В диспетчере IIS выберите сайт, для которого вы хотите разрешить PUT или DELETE.
Нажмите "Фильтрация запросов". Перейдите на вкладку "HTTP-глаголы".
Нажмите ссылку "Разрешить глагол..." на боковой панели.
В появившемся поле введите "УДАЛИТЬ", нажмите "ОК".
Снова нажмите ссылку "Разрешить глагол..." на боковой панели.
В появившемся поле введите "PUT", нажмите "ОК".
Я не уверен, что вы редактировали правильный файл конфигурации. Попробуйте следующие шаги
открыть%userprofile%\ducuments\iisexpress\config\applicationhost.config
По умолчанию ниже указанные записи комментируются в файле applicationhost.config. раскомментируйте эти записи.
<add name="WebDAVModule" image="%IIS_BIN%\webdav.dll" /> <add name="WebDAVModule" />
<add name="WebDAV" path="*"
verb="PROPFIND,PROPPATCH,MKCOL,PUT,COPY,DELETE,MOVE,LOCK,UNLOCK"
modules="WebDAVModule" resourceType="Unspecified" requireAccess="None"
/>
Пробная ошибка не является правильным способом решения этой проблемы. Что необходимо сделать, так это:
- Чтобы определить источник, который блокирует ваши запросы PUT/DELETE
- затем вы можете удалить его, отключить или даже лучше настроить:
1- Чтобы узнать источник, вы должны настроить отслеживание неудачных запросов в IIS.2- У вас есть «Добавить» какие ошибки в журнал . Убедитесь, что вы используете короткий срок службы для этой записи трассировки, чтобы не перегружать вашу систему файлами журнала. IIS будет генерировать отдельный XML-файл для каждого вызова. 3- Сделайте ошибочный запрос с помощью Postman или Swagger, чтобы создать запись об ошибке трассировки. 4- На предыдущем экране вы можете выбрать «Просмотр журналов трассировки», чтобы перейти к сгенерированным файлам журналов. 5- Откройте ошибочный файл журнала с помощью Internet Explorer. И принимать любые сообщения. 6- Обратите внимание на источник, который блокирует ваш запрос. 7- отключите его либо в модулях, либо в обработчике сопоставления из интерфейса IIS, либо в вашем web.config, как показано другими плакатами.
В IIS 8.5/ Windows 2012R2 ничто из упомянутого здесь не работает для меня. Я не знаю, что подразумевается под удалением WebDAV, но это не решило проблему для меня.
Что помогло мне, это следующие шаги;
- Я пошел к менеджеру IIS.
- В левой панели выбрал сайт.
- В левой рабочей области выбрал WebDAV, открыл его двойным щелчком.
- В самой правой панели его отключили.
Сейчас все работает.
Для тех бедолаг, которые ищут способ получить простой файл aspx, обрабатывающий запросы PUT, PATCH и DELETE (да, веб-формы — это прошлый век, но они все еще используются). Это не удаление WebDav или любого из упомянутых ранее исправлений. Это
PageHandlerFactory-Integrated-4.0
Это все, что вам нужно, чтобы получить простой файл aspx (например,
log-request.aspx
) принимаем все глаголы:
<system.webServer>
<handlers>
<remove name="PageHandlerFactory-Integrated-4.0" />
<add name="PageHandlerFactory-Integrated-4.0" path="*.aspx" verb="*" type="System.Web.UI.PageHandlerFactory" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
Другая причина может быть следующей:
Я изменил свой URL для метода Web Api в соответствии с этим ответом:
Url.Action("MyAction", "MyApiCtrl", new { httproute = "" })
Но этот метод создает ссылку как:
/api/MyApiCtrl?action=MyAction
Это правильно работает с запросами GET и POST, но не с запросами PUT или DELETE.
Поэтому я просто заменил его на:
/api/MyApiCtrl
и это решило проблему.
Вы можете конвертировать ваш метод Delete как POST как;
[HttpPost]
public void Delete(YourDomainModel itemToDelete)
{
}