0

Question: Why does my action Add gets hit instead of my delete action?

Error message:

"ExceptionMessage": "Multiple actions were found that match the request: Add on type blog.Controllers.api.UsersController Delete on type blog.Controllers.api.UsersController

My angular delete

$scope.delete = function (email) {

        $http.post('/api/users/Delete', email).success(function() {
            initData();
        });           
    }

alternative tested

 //$http({
        //        url: '/api/users/Delete',
        //        method: 'POST',
        //        data: { 'userEmail': email }
        //    })
        //    .success(function(data, status, headers, config) {
        //        initData();
        //    }).
        //    error(function(data, status, headers, config) {
        //        $scope.showError = true;
        //    });

My MVC 5 api controller

    private readonly UserDataAccess _userDataAccess;

    // GET: Users/Add
    [HttpPost]
    public HttpResponseMessage Add(User user)
    {
        _userDataAccess.AddUser(user);

        return Request.CreateResponse(HttpStatusCode.OK);
    }


// GET: Users/Delete - never gets hit
        [HttpPost]
        public HttpResponseMessage Delete([FromBody]string userEmail)
        {
            _userDataAccess.DelereUserByEmail(userEmail);

            return Request.CreateResponse(HttpStatusCode.OK);
        }

Please note I do not want to solve it using routing.

1
  • Have you tried using ActionName and adding a route to the action before your default route? SO post Commented Aug 7, 2014 at 22:45

3 Answers 3

2

In WebApi you can only have one POST action per Routing. In order to have more than one for the controller class you will need to define new routings.

If you are using WebApi 2 you can benefit from the RoutingAttribute and define these new sub-routes

In your controller class use RoutePrefixAttributte:

[RoutePrefix('api/users')]
public class Users: ApiController{ ...

Followed by your 2 sub-routes:

[Route('add')]
[HttpPost]
public HttpResponseMessage Add(User user){..

[Route('delete')]
[HttpPost]
public HttpResponseMessage Delete([FromBody]string userEmail) {

About Routings

Web Api v1 defines resources globally in the global.asax on application_start event. Assuming you are using Visual Studio 2013 and based on Microsoft's default template your method may look like this:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Register);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
}

WebApi routing configuration occurs here WebApiConfig.Register while your MVC configuration occurs here RouteConfig.RegisterRoutes

Your WebApi routing configuration should look like this

public static class WebApiConfig{
        public static void Register(HttpConfiguration config){            
            config.Routes.MapHttpRoute(
                name: "apiSample",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = System.Web.Http.RouteParameter.Optional  }
            );

     ...

As mentioned previously WebApi v2 introduced the Route Attributes and those can be used along with your Controller class and can facilitate the routing configuration.

For example:

 public class BookController : ApiController{
     //where author is a letter(a-Z) with a minimum of 5 character and 10 max.      
    [Route("html/{id}/{newAuthor:alpha:length(5,10)}")]
    public Book Get(int id, string newAuthor){
        return new Book() { Title = "SQL Server 2012 id= " + id, Author = "Adrian & " + newAuthor };
    }

   [Route("json/{id}/{newAuthor:alpha:length(5,10)}/{title}")]
   public Book Get(int id, string newAuthor, string title){
       return new Book() { Title = "SQL Server 2012 id= " + id, Author = "Adrian & " + newAuthor };
   }
...

You may also refer this other POST with a similar question

How do I write REST service to support multiple Get Endpoints in .net MVC Web API

Sign up to request clarification or add additional context in comments.

1 Comment

thnx for the reply, this would work to the point but I do not want to have specific routing over every action as this is very hard to maitain.
0
[HttpPost]
[Route('api/User/Delete/{userEmail}')]
public HttpResponseMessage Delete([FromBody]string userEmail)
{
}

You can manually configure the route as well

Comments

0

You can add the [HttpDelete] attribute on your delete method in your Api controller and then call it with $http.delete instead.

[HttpDelete]
public IHttpActionResult Delete(string email) {
    return StatusCode(HttpStatusCode.NoContent);
}

To quote the docs of HttpDeleteAttribute Class.

Represents an attribute that is used to restrict an action method so that the method handles only HTTP DELETE requests.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.