只有在本地运行时,DELETE / PUT谓词才会导致Web API中找不到404 Not

时间:2014-01-15 14:56:16

标签: c# asp.net asp.net-mvc iis asp.net-web-api

我知道这是一个常见的问题,我已经完成了很多帖子在SO上提出的所有建议。当我尝试从在本地IIS下运行的MVC5前端使用WebAPI(版本2)删除记录时,我得到404 Not Found响应。以下是我尝试过的事情:

我在我的WebAPI web.config中添加了<system.webServer />下的以下内容:

<system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules runAllManagedModulesForAllRequests="true">
      <remove name="WebDAVModule" />
    </modules>
    <handlers>
      <remove name="WebDAV" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>

我已按照http://geekswithblogs.net/michelotti/archive/2011/05/28/resolve-404-in-iis-express-for-put-and-delete-verbs.aspx中的说明进行操作,这基本上是为了修改IIS“处理程序映射”中的ExtensionlessUrlHandler-Integrated-4.0。它说要双击处理程序,单击“请求限制”和“允许PUT和DELETE谓词”。我做到了这一点,我仍然得到404错误。

我已经完成了IIS重置。

这是调用WebAPI删除方法的MVC5前端代码 - 请注意,当我手动导航到api/bulletinboard/get/{0} {0}为整数时,我会得到有效的JSON响应。下面,contactUrihttp://localhost/SiteName/api/bulletinboard/get/53,返回有效的JSON

[HttpPost, ActionName("Delete")]
        public ActionResult Delete(string appId, int id)
        {
            response = client.GetAsync(string.Format("api/bulletinboard/get/{0}", id)).Result;
            contactUri = response.RequestMessage.RequestUri;
            response = client.DeleteAsync(contactUri).Result;

            if (response.IsSuccessStatusCode)
            {
                return RedirectToAction("MessageList", new { appId = appId });
            }
            else
            {
                LoggerHelper.GetLogger().InsertError(new Exception(string.Format(
                    "Cannot delete message due to HTTP Response Status Code not being successful: {0}", response.StatusCode)));
                return View("Problem");
            }
        }

这是我的WebAPI删除方法:

[HttpDelete]
        public HttpResponseMessage Delete(int id)
        {
            BulletinBoard bulletinBoard = db.BulletinBoards.Find(id);
            if (bulletinBoard == null)
            {
                return Request.CreateResponse(HttpStatusCode.NotFound);
            }

            db.BulletinBoards.Remove(bulletinBoard);

            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
            }

            return Request.CreateResponse(HttpStatusCode.OK, bulletinBoard);
        }

这是我的WebAPI项目中的WebApiConfig.cs:

public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
            config.EnableCors();

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "ApiWithActionName",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            var json = config.Formatters.JsonFormatter;
            json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
            config.Formatters.Remove(config.Formatters.XmlFormatter);

            config.Formatters.Add(new PlainTextFormatter());
        }

问题:我还可以尝试解决此错误吗?从我的本地环境部署到我公司的开发服务器时,这样可以正常工作。

9 个答案:

答案 0 :(得分:9)

对于那些仍在寻找启用DELETE&amp; PUT以下代码解决了我的问题

<validation validateIntegratedModeConfiguration="false" />
<handlers>
  <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
  <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />

  <!--This will enable all Web API verbose-->
  <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>

答案 1 :(得分:3)

如果您使用的是IIS,请确保在请求筛选中将HTTP谓词设置为允许。如果不存在,您可以将其设置为允许侧面。

enter image description here

答案 2 :(得分:3)

我们正在努力使用DELETE / PUT在IIS 8上返回404错误。我们做了以上所有答案,将web.config更改为接受所有动词,在请求过滤中启用put / delete。我们还以多种方式禁用了webDAV。我们发现应用程序池被设置为集成的经典经文(应该是什么)。现在DELETE / PUT动词工作正常。

答案 3 :(得分:1)

我所做的只是通过我的WebAPI项目上的项目属性从使用本地IIS切换到IIS Express,作为一种解决方法。执行此操作并删除记录然后导致405 Method Not Allowed错误。然后我改变了代码行:

response = client.GetAsync(string.Format("api/bulletinboard/get/{0}", id)).Result;
contactUri = response.RequestMessage.RequestUri;
response = client.DeleteAsync(contactUri).Result;

要:

response = client.DeleteAsync(string.Format("api/bulletinboard/delete/{0}", id)).Result;

这很奇怪,因为我有另一个项目运行第一个代码块,它删除记录就好了。无论如何,这解决了我当地的问题。我知道这并没有真正解决我使用本地IIS的主要问题,但这种解决方法对我有用。

答案 4 :(得分:1)

我已经按照https://forums.asp.net/t/1961593.aspx?DELETE+PUT+verbs+result+in+404+Not+Found+in+WebAPI+only+when+running+locally

上的说明进行操作

那只能在您的Web.config中更改这段代码,对我来说很好!

<system.webServer>
    <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>
    <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,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
</system.webServer>

答案 5 :(得分:0)

如果您的项目在IIS下工作而不在IISExpress下,请尝试将IISExpress管理的管道模式设置为Integrated。 在经典管理流水线模式下,PUT和DELETE动词似乎有问题。

祝你好运..

罗伯特。

答案 6 :(得分:0)

Mark Jensen解决方案为我工作。

刚刚将我的应用程序池从“经典”更改为“集成”并且我的请求有效。

答案 7 :(得分:0)

此问题可以通过IIS级别的配置来解决- 打开IIS->选择您的网站-> IIS(部分)->请求过滤-> HHTP动词

删除DELETE动词/或允许DELETE动词

问题将得到解决。

答案 8 :(得分:0)

对我来说,这是一个名为UrlScan的ISAPI模块,我必须将其从应用程序中完全删除。