WebApi 'Multiple actions were found that match the request' error after making call in angular

22,999

Solution 1

The routing on web api works on this way

  • To find the controller, Web API adds "Controller" to the value of the {controller} variable.

  • To find the action, Web API looks at the HTTP method, and then looks for an action whose name begins with that HTTP method name. For example, with a GET request, Web API looks for an action that starts with "Get...", such as "GetContact" or "GetAllContacts". This convention applies only to GET, POST, PUT, and DELETE methods. You can enable other HTTP methods by using attributes on your controller. We’ll see an example of that later. Other placeholder variables in the route template, such as {id}, are mapped to action parameters.

  • Instead of using the naming convention for HTTP methods, you can explicitly specify the HTTP method for an action by decorating the action method with the HttpGet, HttpPut, HttpPost, or HttpDelete attribute.

That's why is matching 2 actions, the name of the method is not used "by default" to match an action. You may have something like this to make it work

public class WebApiInitializer : IInitializableModule
{
    public void Initialize(InitializationEngine context)
    {    
        RouteTable.Routes.MapHttpRoute(
            "CreateJob",
            "api/msi/SBJob/CreateJob",
            defaults: new {Controller = "SBKob", Action = "CreateJob"}
            );

        RouteTable.Routes.MapHttpRoute(
            "GetJob",
            "api/msi/SBJob/GetJob",
            defaults: new {Controller = "SBKob", Action = "GetJob"}
            );              
    }
}

Solution 2

why not be RESTful with your controller instead of having two Posts, when its really a Get?

    public CreateJobResponse Post(CreateJobRequest request)
    {
        return BusProxy.Call<CreateJobRequest, CreateJobResponse>(request);
    }

    public GetJobResponse Get(int id)
    {
        return BusProxy.Call<GetJobRequest, GetJobResponse>(id);
    }
Share:
22,999
sanghas26
Author by

sanghas26

Updated on July 09, 2022

Comments

  • sanghas26
    sanghas26 almost 2 years

    I feel I have the routes, controller and the call correct, but still cannot figure out why I am getting the 'Multiple actions' error. The controller itself makes call to a service bus, but I cannot get it to hit my breakpoint for GetJob. Any ideas?

    Route:

    public class WebApiInitializer : IInitializableModule
        {
            public void Initialize(InitializationEngine context)
            {    
                RouteTable.Routes.MapHttpRoute(
                    "webapimethodroutes",
                    "api/msi/{controller}/{action}",
                    defaults: new {}
                    );
            }
        }
    

    My Job Controller:

    public class SBJobController : ApiController, IJobsController
        {
            [HttpPost]
            public CreateJobResponse CreateJob(CreateJobRequest request)
            {
                return BusProxy.Call<CreateJobRequest, CreateJobResponse>(request);
            }
    
            [HttpPost]
            public GetJobResponse GetJob(GetJobRequest request)
            {
                return BusProxy.Call<GetJobRequest, GetJobResponse>(request);
            }
        }
    

    My service call in angular:

    function getJobs(pRequest) {
                var request = pRequest || {
                    'Ids': [],
                    'JobNumbers': [],
                    'PageNumber': 1,
                    'PageSize': 20,
                };
                return $http.post('/api/msi/SBJob/GetJob', request).error(function (data, status, headers, config) {
                    //logError(data);
                });
            }
    

    The request objects:

    public class CreateJobRequest : RequestBase
        {
            public JobEntity Job { get; set; }
            public AddressEntity Address { set; get; }
        }
    
    public class GetJobRequest: RequestBase, IPageable
        {
            public int PageNumber { set; get; }
            public int PageSize { set; get; }
            public List<Guid> Ids { set; get; }
            public List<string> JobNumbers { set; get; }
            public Guid ChildOfCustomer { set; get; }
            public Guid ChildOfContact { set; get; }
            public JobTypeEnum JobType { get; set; }
        }
    

    The exact error I am getting:

    {
        "Message": "An error has occurred.",
        "ExceptionMessage": "Multiple actions were found that match the request: \r\nCreateJob on type MSI.ServiceBus.ServiceControllers.SBJobController\r\nGetJob on type MSI.ServiceBus.ServiceControllers.SBJobController",
        "ExceptionType": "System.InvalidOperationException",
        "StackTrace": "   at System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext controllerContext)\r\n   at System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext controllerContext)\r\n   at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"
    }
    
  • user2378769
    user2378769 about 9 years
    both routes have the same Action in the defaults, is that correct? defaults: new {Controller = "SBKob", Action = "CreateJob"}