IIS 8.5上的HTTP PUT失败

时间:2014-02-19 05:01:18

标签: asp.net http iis asp.net-web-api

这似乎越来越深入IIS而不是我擅长!所以我有一个适用于GET和POST的Web API控制器。第一个屏幕截图显示了GET的处理。一切都很好,我得到了回应。

View Full Size Success Detail

然后我提出了一个PUT请求,这一切都崩溃了。它似乎穿过ManagedPipelineHandler,然后进入DefaultDocumentModule并以405失败。

View Full Size Fail Summary

View Full Size Fail Details

没有安装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>

尽管如此,请求未能由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) };
    }
}

似乎我在请求生命周期的早期错过了手。

FREB似乎显示了PUT的GENERAL_SHILD_REQUEST_START,不知道为什么托管管道正在创建最终属于无法处理PUT的DefaultDocumentModule的额外子请求。

2 个答案:

答案 0 :(得分:1)

查看您的场景(感谢您分享您的repro项目),问题是投影将webapi放在项目内的/ api文件夹中。

特别是还有/ api / products,所以当http / ap的/ api /产品被命中时,IIS将其视为目录浏览请求,并拒绝在其上提供PUT动词。

解决方案:重命名api文件夹,通常尽量不要在调用REST API的位置映射文件夹。这不是部署中的问题,但在本地Web应用程序上,该文件夹就在那里,IIS首先处理它。

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

<modules runAllManagedModulesForAllRequests="true" />

这将让ASP.NET在IIS之前获得第一次破解,但这不是推荐的做法,只是为了解决这样的小问题。

答案 1 :(得分:0)

我有类似的问题。我的PHP REST Api在IIS 8.5中为动词PUT和DELETE返回404。事实证明,默认情况下,快速CGI模块没有收到所有动词。

要修复它,我将其添加到web.config:

<system.webServer>
    <handlers>
        <remove name="PHP55_via_FastCGI" />
        <add name="PHP55_via_FastCGI" path="*.php" verb="*" modules="FastCgiModule" scriptProcessor="C:\Program Files (x86)\PHP\v5.5\php-cgi.exe" resourceType="Either" requireAccess="Script" />
    </handlers>
    ...

这适用于PHP,但我希望这可以帮助某人。