ASP.NET 网页 Api "The requested resource does not support http method PUT/DELETE"
ASP.NET Web Api "The requested resource does not support http method PUT/DELETE"
我正在使用 ASP.NET/C# 构建一个 API。但是,在尝试发出 PUT 或 DELETE 请求时,我收到以下错误:
"The requested resource does not support http method PUT (or DELETE)"
我知道这个问题之前已经讨论过;但是,我查看了相关问题的回复(包括this one),但仍未找到解决方案。我已禁用 WebDAV 并确保在 ExtensionlessUrlHanlder 中允许使用动词。我的web.config的"webserver"部分如下:
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
<remove name="WebDAVModule"/>
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" preCondition="managedHandler" />
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" preCondition="managedHandler" />
<add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" preCondition="managedHandler" />
</modules>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="WebDAV" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
<validation validateIntegratedModeConfiguration="false" />
</system.webServer>
控制器如下:
namespace MidamAPI.Controllers
{
[RoutePrefix("SupplyItems")]
public class SupplyItemsController : ApiController
{
UnitOfWork worker = new UnitOfWork();
[Route("")]
[HttpGet]
public string Get()
{
IEnumerable<SupplyItemsDTO> dtoList = Mapper.Map<List<SupplyItem>, List<SupplyItemsDTO>>(worker.SupplyItemRepo.Get().ToList());
return JsonConvert.SerializeObject(dtoList);
}
[Route("{propertyType}")]
public string Get(String propertyType = "BK")
{
IEnumerable<SupplyItemsDTO> dtoList = null;
if (propertyType.Equals("POPEYES", StringComparison.CurrentCultureIgnoreCase))
{dtoList = Mapper.Map<List<PopeyesSupplyItem>, List<SupplyItemsDTO>>(worker.PopeyesItemRepo.Get().ToList());
}
dtoList = Mapper.Map<List<BKSupplyItem>, List<SupplyItemsDTO>>(worker.BKItemRepo.Get().ToList());
return JsonConvert.SerializeObject(dtoList);
}
[Route("{id:int}")]
public string Get(int id)
{
SupplyItemsDTO dto = Mapper.Map<SupplyItem, SupplyItemsDTO>(worker.SupplyItemRepo.GetByID(id));
return JsonConvert.SerializeObject(dto);
}
[Route("")]
[HttpPost]
public HttpResponseMessage Post([FromBody]SupplyItem itm)
{
try
{
worker.SupplyItemRepo.Insert(itm);
worker.Save();
return Request.CreateResponse(HttpStatusCode.OK, itm);
}
catch (Exception ex)
{
return Request.CreateResponse(HttpStatusCode.BadRequest, ex);
}
}
[Route("")]
[HttpDelete]
public HttpResponseMessage Delete(int id)
{
try
{
SupplyItem itm = worker.SupplyItemRepo.GetByID(id);
worker.SupplyItemRepo.Delete(itm);
worker.Save();
return Request.CreateResponse(HttpStatusCode.OK, itm);
}
catch(Exception ex)
{
return Request.CreateResponse(HttpStatusCode.BadRequest, ex);
}
}
[Route("")]
[HttpPut]
public HttpResponseMessage Put(int id, SupplyItem item) {
try
{
item.ID = id;
worker.SupplyItemRepo.Update(item);
return Request.CreateResponse(HttpStatusCode.OK, item);
}
catch(Exception ex)
{
return Request.CreateResponse(HttpStatusCode.BadRequest, ex);
}
}
}
}
GET 和 POST 调用按预期工作。我不想更改 applicationhost.config 文件,真的不想以任何方式修改 Web 服务器(因为这是我的开发机器),或者使用可能代表安全漏洞的 headers。
响应headers:
Access-Control-Allow-Credentials →true
Access-Control-Allow-Headers →Origin, X-Requested-With, Content-Type, Accept, X-Token,Authorization
Access-Control-Allow-Methods →GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Methods →GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin →*
Allow →GET
Cache-Control →no-cache
Content-Length →72
Content-Type →application/json; charset=utf-8
Date →Tue, 10 Oct 2017 13:39:03 GMT
Expires →-1
Pragma →no-cache
Server →Microsoft-IIS/8.0
X-AspNet-Version →4.0.30319
X-Powered-By →ASP.NET
X-SourceFiles →=?UTF-8?B?QzpcVmlzdWFsIFN0dWRpbyBQcm9qZWN0c1xNaWRhbWVyaWNhQVBJXE1pZGFtQVBJXHN1cHBseWl0ZW1zXDQ1NA==?=
IIS 日志中的请求:
2017-10-10 13:27:35 ::1 PUT /supplyitems/454 - 57263 - ::1 PostmanRuntime/6.3.2 - 405 0 0 0
我的路线:
config.Routes.MapHttpRoute(
name: "DefaultAPI",
routeTemplate: "{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
如有任何建议,我们将不胜感激。我正在使用 IIS Express。谢谢。
我遇到那个错误的经历是:
你得到这个可能是因为你安装了一些额外的 IIS 模块:
WebDAV
如果您不需要它,我会从您的 IIS 中删除它。
此模块是 IIS 角色的一部分。
要摆脱它,请转到:
Windows 功能 -> 转 Windows 功能 On/Off -> Internet 信息服务 -> 万维网服务 -> 通用 HTTP 功能 -> WebDAV 发布。
如果你想保持它,我认为你需要添加 PUT/DELETE 到 ISAPI 过滤器。
关于这里的更多解释:
您可能还安装了一些额外的模块。即使您修复了这些问题,您的请求和路由也不会匹配。
您的路由配置将被忽略,因为您已经使用路由属性明确设置了路由。您应该将 DELETE 方法路由属性更新为 [Route("{id:int}")]
。对于 PUT 方法,你在做什么有点不清楚,但我假设你想做这样的事情:
[Route("{id:int}")]
[HttpPut]
public HttpResponseMessage Put([FromUrl]int id, [FromBody]SupplyItem item) {
...
我正在使用 ASP.NET/C# 构建一个 API。但是,在尝试发出 PUT 或 DELETE 请求时,我收到以下错误:
"The requested resource does not support http method PUT (or DELETE)"
我知道这个问题之前已经讨论过;但是,我查看了相关问题的回复(包括this one),但仍未找到解决方案。我已禁用 WebDAV 并确保在 ExtensionlessUrlHanlder 中允许使用动词。我的web.config的"webserver"部分如下:
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
<remove name="WebDAVModule"/>
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" preCondition="managedHandler" />
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" preCondition="managedHandler" />
<add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" preCondition="managedHandler" />
</modules>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="WebDAV" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
<validation validateIntegratedModeConfiguration="false" />
</system.webServer>
控制器如下:
namespace MidamAPI.Controllers
{
[RoutePrefix("SupplyItems")]
public class SupplyItemsController : ApiController
{
UnitOfWork worker = new UnitOfWork();
[Route("")]
[HttpGet]
public string Get()
{
IEnumerable<SupplyItemsDTO> dtoList = Mapper.Map<List<SupplyItem>, List<SupplyItemsDTO>>(worker.SupplyItemRepo.Get().ToList());
return JsonConvert.SerializeObject(dtoList);
}
[Route("{propertyType}")]
public string Get(String propertyType = "BK")
{
IEnumerable<SupplyItemsDTO> dtoList = null;
if (propertyType.Equals("POPEYES", StringComparison.CurrentCultureIgnoreCase))
{dtoList = Mapper.Map<List<PopeyesSupplyItem>, List<SupplyItemsDTO>>(worker.PopeyesItemRepo.Get().ToList());
}
dtoList = Mapper.Map<List<BKSupplyItem>, List<SupplyItemsDTO>>(worker.BKItemRepo.Get().ToList());
return JsonConvert.SerializeObject(dtoList);
}
[Route("{id:int}")]
public string Get(int id)
{
SupplyItemsDTO dto = Mapper.Map<SupplyItem, SupplyItemsDTO>(worker.SupplyItemRepo.GetByID(id));
return JsonConvert.SerializeObject(dto);
}
[Route("")]
[HttpPost]
public HttpResponseMessage Post([FromBody]SupplyItem itm)
{
try
{
worker.SupplyItemRepo.Insert(itm);
worker.Save();
return Request.CreateResponse(HttpStatusCode.OK, itm);
}
catch (Exception ex)
{
return Request.CreateResponse(HttpStatusCode.BadRequest, ex);
}
}
[Route("")]
[HttpDelete]
public HttpResponseMessage Delete(int id)
{
try
{
SupplyItem itm = worker.SupplyItemRepo.GetByID(id);
worker.SupplyItemRepo.Delete(itm);
worker.Save();
return Request.CreateResponse(HttpStatusCode.OK, itm);
}
catch(Exception ex)
{
return Request.CreateResponse(HttpStatusCode.BadRequest, ex);
}
}
[Route("")]
[HttpPut]
public HttpResponseMessage Put(int id, SupplyItem item) {
try
{
item.ID = id;
worker.SupplyItemRepo.Update(item);
return Request.CreateResponse(HttpStatusCode.OK, item);
}
catch(Exception ex)
{
return Request.CreateResponse(HttpStatusCode.BadRequest, ex);
}
}
}
}
GET 和 POST 调用按预期工作。我不想更改 applicationhost.config 文件,真的不想以任何方式修改 Web 服务器(因为这是我的开发机器),或者使用可能代表安全漏洞的 headers。
响应headers:
Access-Control-Allow-Credentials →true
Access-Control-Allow-Headers →Origin, X-Requested-With, Content-Type, Accept, X-Token,Authorization
Access-Control-Allow-Methods →GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Methods →GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin →*
Allow →GET
Cache-Control →no-cache
Content-Length →72
Content-Type →application/json; charset=utf-8
Date →Tue, 10 Oct 2017 13:39:03 GMT
Expires →-1
Pragma →no-cache
Server →Microsoft-IIS/8.0
X-AspNet-Version →4.0.30319
X-Powered-By →ASP.NET
X-SourceFiles →=?UTF-8?B?QzpcVmlzdWFsIFN0dWRpbyBQcm9qZWN0c1xNaWRhbWVyaWNhQVBJXE1pZGFtQVBJXHN1cHBseWl0ZW1zXDQ1NA==?=
IIS 日志中的请求:
2017-10-10 13:27:35 ::1 PUT /supplyitems/454 - 57263 - ::1 PostmanRuntime/6.3.2 - 405 0 0 0
我的路线:
config.Routes.MapHttpRoute(
name: "DefaultAPI",
routeTemplate: "{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
如有任何建议,我们将不胜感激。我正在使用 IIS Express。谢谢。
我遇到那个错误的经历是:
你得到这个可能是因为你安装了一些额外的 IIS 模块:
WebDAV
如果您不需要它,我会从您的 IIS 中删除它。
此模块是 IIS 角色的一部分。 要摆脱它,请转到: Windows 功能 -> 转 Windows 功能 On/Off -> Internet 信息服务 -> 万维网服务 -> 通用 HTTP 功能 -> WebDAV 发布。
如果你想保持它,我认为你需要添加 PUT/DELETE 到 ISAPI 过滤器。
关于这里的更多解释:
您可能还安装了一些额外的模块。即使您修复了这些问题,您的请求和路由也不会匹配。
您的路由配置将被忽略,因为您已经使用路由属性明确设置了路由。您应该将 DELETE 方法路由属性更新为 [Route("{id:int}")]
。对于 PUT 方法,你在做什么有点不清楚,但我假设你想做这样的事情:
[Route("{id:int}")]
[HttpPut]
public HttpResponseMessage Put([FromUrl]int id, [FromBody]SupplyItem item) {
...