Marcos Foster
Marcos Foster

Reputation: 67

Web API DELETE - The parameters dictionary contains a null entry for parameter 'id'

I'm trying to use ASP.NET Web API DELETE to remove a record from a database.

Here is the jQuery AJAX call:

var row = $(dom).closest("tr");
var text = row.find(".tId").text();
var tId = +(text);

//HTTP DELETE method
$.ajax({
    url: 'api/transaction/delete',
    type: 'DELETE',
    data: {
        'id': tId
    },
    success: function (result) {
        //Success logic
        //Refresh table?
        console.log("Successfully deleted transaction " + tId);
    },
    error: function () {
        console.log("Error deleting transaction");
    }
});

Here is the controller code:

    [HttpDelete]
    [Route("api/transaction/delete/{id}")]
    public HttpResponseMessage Delete(int id)
    {
        if (DataLayer.DataLayer.DeleteTransaction(id))
        {
            return Request.CreateResponse(HttpStatusCode.OK);
        }
        else
        {
            return null;
        }
    }

And the Http routing from Global.asax.cs

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

Looking at the request in Fiddler, the error returned says The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.String Get(Int32)' in 'SemanticUI_Playground.Controllers.TransactionController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.

What's odd though is that - also in Fiddler - I can see the the request has id=1045.

I've obviously not done something correct; my guess is with the routing. If I change the AJAX request URL to api/transaction rather than api/transaction/delete I get a different error (to the effect of DELETE is not supported or similar).

Removing the id parameter altogether means that the breakpoint in TransactionController is met, but obviously useless!

I understand this is a bit ham-fisted (this project is just a personal one to teach myself about web development), please accept my apologies for my obvious lack of understanding!

Upvotes: 0

Views: 793

Answers (1)

Richard Ockerby
Richard Ockerby

Reputation: 484

The benefit of adding in the different type of requests is that you don't need to have multiple URLs to perform actions; you call them via the request type (DELETE, GET, POST etc). What I would do in the example you gave is remove the additional routing you've declared with [Route("api/transaction/delete/{id}")] and call it using:

$.ajax({
    url: '/api/transaction/' + tId,
    type: 'DELETE',
    success: function (result) {
        //Success logic
        //Refresh table?
        console.log("Successfully deleted transaction " + tId);
    },
    error: function () {
        console.log("Error deleting transaction");
    }
});

Or similarly keep the code route and send the request to '/api/transaction/delete/' + tId.

I've found that you will also need to register the attribute routing with RouteTable.Routes.MapHttpAttributeRoutes in your Global.asax.cs before your MapHttpRoute call. Check this out for a bit of guidance on that (ordering of the registration code is important!)

Upvotes: 2

Related Questions