IIS 8.5上的HTTP PUT失败

Mon*_*ane 5 asp.net iis http asp.net-web-api

这似乎比我擅长的要深入IIS!因此,我有一个非常适合GET和POST的Web API控制器。第一个屏幕截图显示了对GET的处理。一切都很好,我得到了回应。

查看全尺寸 成功细节

但是随后我提出了一个PUT请求,一切都崩溃了。它似乎遍历ManagedPipelineHandler,然后陷入DefaultDocumentModule,并失败,并出现405。

查看全尺寸 失败摘要

查看全尺寸 失败详情

没有安装WebDAV,无论如何我都尝试在web.config级别将其删除。处理程序被覆盖以支持PUT。

<handlers>
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <remove name="OPTIONSVerbHandler" />
  <remove name="TRACEVerbHandler" />
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" />
</handlers>
Run Code Online (Sandbox Code Playgroud)

尽管如此,ASP.NET仍无法处理该请求,因此我正在寻找有关调试的想法?这是失败的操作方法,即PUT和起作用的方法,即GET。

public class ProductsController : ApiController
{
    [HttpPut]
    [Route("api/products")]
    public AddProductResponse AddProduct(AddProductRequest request)
    {
        return new AddProductResponse(); 
    }

    [HttpGet]
    [Route("api/products/manufacturers")]
    public ManufacturersResponse GetProductManufacturers()
    {
        var productService = new ProductService();
        var manufacturers = productService.GetManufacturers();
        return new ManufacturersResponse { Manufacturers = manufacturers.OrderBy(m => m.BusinessName) };
    }
}
Run Code Online (Sandbox Code Playgroud)

似乎我错过了请求生命周期早期的传递。

FREB似乎显示了PUT的GENERAL_SHILD_REQUEST_START,但不确定为什么托管管道正在创建该额外的子请求,该子请求最终落入无法处理PUT的DefaultDocumentModule。

Yis*_*zer 2

查看您的场景(感谢分享您的重现项目),问题是预计将 webapi 放置在项目内的 /api 文件夹中。

具体来说,还有 /api/products,因此当 http put 访问路径 /api/products 时,IIS 将其视为目录浏览请求,并拒绝在其上提供 PUT 动词。

解决方案:重命名 api 文件夹,并且一般情况下尽量不要将文件夹映射到调用 REST API 的位置。这在部署中不会成为问题,但在本地 Web 应用程序上,该文件夹就在那里,IIS 首先会处理它。

另一种解决方案(尽管不太推荐)是使用

<modules runAllManagedModulesForAllRequests="true" />
Run Code Online (Sandbox Code Playgroud)

这将使 ASP.NET 在 IIS 之前获得首次破解,但是不建议仅为了解决此类小问题而采用这种做法。