Search code examples
c#asp.net-mvc-4jqgridhttp-status-code-405methodnotfound

jqGrid - Delete operation Error- "error Status: 'Method Not Allowed'. Error code: 405"


I am creating a jqGrid with MVC4 WebApi. I able to populate data into the grid but getting error while clicking on delete button. Here is my front end(htm) code. :

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta charset="utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <title>My First Grid</title>
    <link href="../Content/Site.css" rel="stylesheet"/>
    <!--<link href="../Content/themes/base/jquery.ui.all.css" rel="stylesheet"/>-->
    <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/redmond/jquery-ui.css"/>
    <!--<link href="../Content/ui.jqgrid.css" rel="stylesheet"/>-->
    <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/free-jqgrid/4.9.2/css/ui.jqgrid.css"/>
    <link rel="stylesheet" href="http://netdna.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css"/>
    <style>
        html, body {
            font-size: 75%;
        }
    </style>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <!--<script src="../Scripts/jquery-1.9.1.min.js"></script>-->
    <!--<script src="../Scripts/jquery-ui-1.10.4.js"></script>-->
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
    <script src="../Scripts/free-jqGrid/jquery.jqgrid.src.js"></script>

    <script>
        //<![CDATA[
        $(document).ready(function () {
            "use strict";
            var apiUrl = "/WebApiOne/api/task/";
            jQuery("#gridMain").jqGrid({
                url: apiUrl,
                editurl: apiUrl,
                datatype: "json",
                gridview: true,
                height: "auto",
                iconSet: "fontAwesome",
                autoencode: true,
                sortable: true,
                viewrecords: true,
                loadonce: true,
                jsonReader: { id: "TaskID" },
                prmNames: { id: "TaskID" },
                colNames: ["TaskID", "ProjectID", "ProjectName", "TaskName", "TaskStatus"],
                colModel: [
                    { name: "TaskID", width: 60, key: true, editable: false, sorttype: "int" },
                    { name: "ProjectID", width: 90 },
                    { name: "ProjectName", width: 190 },
                    { name: "TaskName", width: 170, align: "right" },
                    { name: "TaskStatus", width: 170, align: "right" }
                ],
                cmTemplate: { editable: true },
                //autowidth: true,
                formEditing: {
                    width: 400,
                    reloadGridOptions: { fromServer: true },
                    serializeEditData: function (postdata) {
                        var copyOfPostdata = $.extend({}, postdata);
                        if (postdata.TaskID === "_empty") { // ADD operation
                            postdata.TaskID = 0; // to be easy to deserialize
                        }
                        delete copyOfPostdata.oper; // remove unneeded oper parameter
                        return copyOfPostdata;
                    }
                },
                formDeleting: {
                    mtype: "DELETE",
                    reloadGridOptions: { fromServer: true },

                    serializeDelData: function () {
                        return ""; // don't send any body for the HTTP DELETE
                    },
                    onclickSubmit: function (options, postdata) {
                        var p = $(this).jqGrid("getGridParam"); // get reference to internal parameters
                        p.datatype = "json";
                        options.url = apiUrl + encodeURIComponent(postdata[0]);
                    }
                },
                pager: true
            }).jqGrid("navGrid", {addtext:"add" , deltext:"del", edittext:"edit"}, {
                mtype: "PUT",
                onclickSubmit: function (options, postdata) {
                    //var p = $(this).jqGrid("getGridParam"); // get reference to internal parameters
                    //p.datatype = "json"; // reset datatype to reload from the server
                    options.url = apiUrl + encodeURIComponent(postdata[this.id + "_id"]);
                }
            }).jqGrid("filterToolbar") // add searching toolbar for local sorting (bacsue of loadonce:true) in the grid
                .jqGrid("gridResize");
        });
        //]]>
    </script>
</head>
<body>
    <table id="gridMain"></table>
</body>
</html>

I researched alot on this, made lot of variations but result was always same :(. Tried the solution provided here but still no success. I kept a breakpoint on Get and Delete method of my server side code. Only Get method hits the breakpoint when the page loads. Delete method breakpoint is never hitting. Here goes my Server Side Code :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Mvc;

namespace WebApiOne.Controllers
{
    public class Task
    {
        public int TaskID { get; set; }
        public int ProjectID { get; set; }
        public string ProjectName { get; set; }
        public string TaskName { get; set; }
        public string TaskStatus { get; set; }
    }

    public class TaskController : ApiController
    {
        // GET api/task
        public IEnumerable<Task> Get()
        {
            Task[] tasks = new Task[2];

            tasks[0] = new Task()
            {
                TaskID = 1,
                ProjectID = 1,
                ProjectName = "ProjectOne",
                TaskName = "FirstPage Development",
                TaskStatus = "InProgress"

            };

            tasks[1] = new Task()
            {
                TaskID = 2,
                ProjectID = 1,
                ProjectName = "ProjectOne",
                TaskName = "Second Page Development",
                TaskStatus = "Yet To Start"

            };

            return tasks;
        }

        // DELETE api/task/5
        public void Delete(int id)
        {
            // Delete row in DB.
        }   

    }
}

Here is the fiddler trace of Delete Request:

DELETE http://localhost/WebApiOne/api/task/2 HTTP/1.1
Host: localhost
Connection: keep-alive
Accept: */*
Origin: http://localhost
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36
Referer: http://localhost/WebApiOne/Views/JqGrid.htm
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8

Here is the screen shot of the error :

All suggestions are invited :).


Solution

  • I can't reproduce the problem on my computer. In any way I'm sure that you can the problem with configuration on the server side. For example the article describes close problem. Probably you have conflict with WebDAV inctalled on IIS. The article suggest to add include in the <handlers> of <system.webServer> the line <remove name="WebDAV" />. For example you can modify the following <system.webServer> section of web.config

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

    to the following

    <system.webServer>
        <validation validateIntegratedModeConfiguration="false" />
        <modules runAllManagedModulesForAllRequests="true" />
        <handlers>
            <remove name="WebDAV" /> <!-- The Modification !!! -->
            <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
            <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" />
        </handlers>
    </system.webServer>
    

    Additionally you can replace the line

    <modules runAllManagedModulesForAllRequests="true" />
    

    of <system.webServer> section of web.config to

    <modules runAllManagedModulesForAllRequests="true">
        <remove name="WebDAVModule"/> <!-- add this -->
    </modules>
    

    see the answer.

    UPDATED: If nothing above will not help you then I would recommend you just uninstall WebDAV module to verify whether the reason of our problem is really WebDAV. If you don't need WebDAV I would recommend to hold the module uninstalled. If you could need WebDAV then I would recommend you to post the question on https://serverfault.com/ for example. If uninstalling of WebDAV solves the problem that you can be sure that you have the problem with the corresponding configuration of IIS only and with the usage of WebDAV module which you don't need for working of the web site.