ASP.NET MVC4 + Web API控制器删除请求>> 404错误

16
我有一个VS2012 MVC4解决方案,其中我测试Web API控制器。
我成功地测试了GET、POST和PUT,但DELETE仍然给我带来了http 404错误。当我在我的api控制器中设置一个“DeleteMovie”操作的断点时,断点永远不会被触发。
我阅读了很多关于这个问题的帖子,但没有一个能帮助我。
这是我的DELETE API控制器:
    [HttpDelete]
    public HttpResponseMessage DeleteMovie(int id)
    {    
        // Delete the movie from the database     
        // Return status code    
        return new HttpResponseMessage(HttpStatusCode.NoContent);

    }

这是我的HTML页面:

<script type="text/javascript">

    deleteMovie(1, function ()
    {
        alert("Movie deleted!");
    });

    function deleteMovie(id, callback) {
        $.ajax({
            url: "/api/Movie",
            data: JSON.stringify({ id: id }),
            type: "DELETE",
            contentType: "application/json;charset=utf-8",
            statusCode: {
                204: function () {
                    callback();
                }
            }
        });
    }

</script>

我的经典路线如下:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }

我的API路由如下:
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "ActionApi", 
            routeTemplate: "api/{controller}/{action}/{id}", 
            defaults: new { id = RouteParameter.Optional }
        );

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

在我的解决方案属性中,我使用“使用本地IIS Web服务器”,勾选“使用IIS Express”。我也尝试过使用“使用Visual Studio开发服务器”,但是问题一样。有什么想法吗?谢谢。

在您的浏览器中,如果您使用调试工具,您能否捕获由jQuery实际输出的URL,并查看它是否正确? - Russ Clarke
4个回答

47

如果您收到的错误是来自IIS的HTML内容类型,错误代码为404.0

请确保您的web.config文件中有Web API模板添加的该部分配置。 默认情况下,IIS不会服务于DELETE动词,而此配置将覆盖此行为。

  <system.webServer>
    <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>

1
+1 我开始使用MVC项目,但只想用它来进行WebAPI。因此,在删除我认为是MVC特定配置后,我的DELETE请求出现了404错误。谢谢。 - Luke Baulch

18

HTTP DELETE 没有消息体。你需要将 ID 作为查询字符串参数传递。


1
谢谢。你是对的!我在这篇博客文章中找到了代码:http://stephenwalther.com/archive/2012/03/05/introduction-to-the-asp-net-web-api.aspx,所以我真的不认为会有这样的问题! - Bronzato

1
根据Russell的回答,我查看了web config并在handlers方法中找到了两行代码。
....
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />

我已经移除了最后一个并且它有效了。
只是一个客户端使用的例子(typescript)。
    public deleteComment(commentId: number) {
        var url = 'api/comments/' + commentId;
        return this.$http.delete(url);
    }

并且服务器端

    [Route("{id:int}")]
    public async Task<IHttpActionResult> Delete(int id){
        await _snippetService.DeleteComment(id);
        return Ok();
    }

1
我在Mac上使用Dotnet Core时遇到了404错误。
在我的情况下,我将属性注释从HttpDelete更改为HttpDelete("{id}")

1
好的,知道了。谢谢分享。 - Bronzato

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接