2

I have a stored proc in SQL called "person_connections_delete". I have written a controller to call the stored proc however, this error message keeps coming up

"message": "No HTTP resource was found that matches the request URI 'http://localhost:3024/api/personconnections/delete'.", "messageDetail": "No action was found on the controller 'PersonConnections' that matches the request."

Here is the stored proc. I'm passing three parameters into the stored proc for the delete.

ALTER PROC [dbo].[person_connections_delete]
    @PersonId INT,
    @FriendId INT,
    @Status INT
AS
    /*
        DECLARE
            @_personId INT = 1,
            @_friendId INT = 200,
            @_status INT = 1
        EXEC person_connections_delete
            @_personId,
            @_friendId,
            @_status
    */
BEGIN
    DELETE
        person_connections
    WHERE
        PersonId = @PersonId and FriendId = @FriendId
    IF (@Status = 1)
    DELETE
        person_connections
    WHERE
        PersonId = @FriendId and FriendId = @PersonId
END

The service and controller. in C#:

public void Delete(int personId, int friendId, int status)
        {
            _dataProvider.ExecuteNonQuery(
                "person_connections_delete",
                inputParamMapper: delegate (SqlParameterCollection paramCol)
                {
                    paramCol.AddWithValue("@PersonId", personId);
                    paramCol.AddWithValue("@FriendId", friendId);
                    paramCol.AddWithValue("@Status", status);
                }
            );
        }

[AllowAnonymous]
    [RoutePrefix("api/personconnections")]
    public class PersonConnectionsController : ApiController
    {
        private IPersonConnectionsService _personConnectionsService;

[HttpDelete]
        [Route("delete")]
        public HttpResponseMessage Delete(int personId, int friendId, int status)
        {
            try {
                if (ModelState.IsValid) {
                    ItemResponse<PersonConnectionsDeleteDomain> resp = new ItemResponse<PersonConnectionsDeleteDomain>();
                    _personConnectionsService.Delete(personId, friendId, status);
                    return Request.CreateResponse(HttpStatusCode.OK, resp);
                } else {
                    return Request.CreateResponse(HttpStatusCode.NotModified, ModelState);
                }
            } catch (Exception ex) {
                return Request.CreateResponse(HttpStatusCode.BadRequest, ex);
            }
        }
}

enter image description here

jarlh
  • 42,561
  • 8
  • 45
  • 63
twofer
  • 77
  • 7
  • I suggest taking a look at https://www.nuget.org/packages/routedebugger to see how your route is being resolved. – Matt Evans Jan 03 '19 at 06:55

1 Answers1

0

See Parameter Binding in ASP.NET Web API. WebAPI can't bind multiple parameters from body natively.

When a parameter has [FromBody], Web API uses the Content-Type header to select a formatter. In this example, the content type is "application/json" and the request body is a raw JSON string (not a JSON object).

At most one parameter is allowed to read from the message body. So this will not work:

// Caution: Will not work!    
public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }

The reason for this rule is that the request body might be stored in a non-buffered stream that can only be read once.

There are other SO questions that ask how to achieve this, like this one. But unless you have a real reason to do so, I think you are better off using attribute routing or query string parameters.

Monticola Explorator
  • 1,188
  • 13
  • 20
  • You mentioned that WebAPI can't bind multiple POST parameters, but I'm assuming DELETE is the same? – twofer Jan 03 '19 at 07:13
  • Sorry, my bad I did not notice it was a delete method. But yes, it should be the same as a post method. The documentation does not say anything about binding from body limitations not applying to delete method or applying only to post methods. I have edited my answer. – Monticola Explorator Jan 03 '19 at 07:47