简体   繁体   English

IIS 8.5上的HTTP PUT失败

[英]HTTP PUT Failing on IIS 8.5

This seems to be getting deeper into IIS than I'm good at! 这似乎越来越深入IIS而不是我擅长! So I have a Web API controller that is working great for GET and POST. 所以我有一个适用于GET和POST的Web API控制器。 The first screenshot shows a handling of a GET. 第一个屏幕截图显示了GET的处理。 Everything was great I get a response. 一切都很棒,我得到了回应。

View Full Size 查看全尺寸 成功细节

But then I make a PUT request and it all falls apart. 但后来我提出了一个PUT请求,这一切都崩溃了。 It seems to cruise through the ManagedPipelineHandler and then falls through to the DefaultDocumentModule and fails with a 405. 它似乎穿过ManagedPipelineHandler,然后进入DefaultDocumentModule并以405失败。

View Full Size 查看全尺寸 失败摘要

View Full Size 查看全尺寸 失败详情

There is no WebDAV installed and I've tried to remove it anyway at the web.config level. 没有安装WebDAV,我试图在web.config级别删除它。 Handlers are overridden to support PUT. 处理程序被覆盖以支持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>

Despite this the request is failing to be handled by ASP.NET and I'm looking for some ideas on debugging? 尽管如此,ASP.NET无法处理请求,我正在寻找有关调试的一些想法? Here is the action method that fails, the PUT and one that works, a GET. 这是失败的动作方法,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) };
    }
}

Seems I missed the hand off early in the request lifecycle. 似乎我在请求生命周期的早期错过了手。

FREB seems to show the GENERAL_SHILD_REQUEST_START for the PUT, not sure why the managed pipeline is creating that extra child request that ultimately falls to the DefaultDocumentModule which can't handle a PUT. FREB似乎显示了PUT的GENERAL_SHILD_REQUEST_START,不知道为什么托管管道正在创建最终落入无法处理PUT的DefaultDocumentModule的额外子请求。

Looked at your scenario (thanks for sharing you repro project), and the issue is that the projected placed the webapi in a /api folder inside the project. 看看你的场景(感谢分享你的repro项目),问题是投影将webapi放在项目内的/ api文件夹中。

Specifically there was also /api/products, so when the path /api/products was hit for the http put, IIS seen it as a directory browsing request, and refused to serve a PUT verb on it. 具体来说还有/ api / products,所以当http / ap的/ api /产品被命中时,IIS将其视为目录浏览请求,并拒绝在其上提供PUT动词。

Solution: Rename the api folder, and in general try not to map folders right where REST APIs are being called. 解决方案:重命名api文件夹,通常尝试不在正在调用REST API的位置映射文件夹。 This wouldn't have been an issue in deployment but on the local Web Application the folder is there and IIS gets to handle it first. 这不是部署中的问题,但在本地Web应用程序上,文件夹就在那里,IIS首先处理它。

Another solution (though less recommended) is to use 另一种解决方案(虽然不太推荐)是使用

<modules runAllManagedModulesForAllRequests="true" />

That will let ASP.NET get a first crack ahead of IIS, this is however not a recommended practice just to solve a small problem like this. 这将让ASP.NET在IIS之前获得第一次破解,但这不是一个推荐的做法,只是为了解决这样的小问题。

I had a similar problem. 我遇到了类似的问题。 My PHP REST Api was returning 404 for the verbs PUT and DELETE in IIS 8.5. 我的PHP REST Api在IIS 8.5中为动词PUT和DELETE返回404。 Turns out that the Fast CGI Module wasn't receiving all verbs by default. 事实证明,默认情况下,快速CGI模块没有收到所有动词。

To fix it, I added this to web.config: 要修复它,我将其添加到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>
    ...

This is for PHP, but I hope this helps someone. 这适用于PHP,但我希望这对某人有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM