Nitika Pondith
Nitika Pondith

Reputation: 57

Multiple actions were found that match the request in mvc5 api application

When I try to hit my API controller using get url I am getting following error:

Multiple actions were found that match the request:

IsStoreKeyValid on type BlexzWeb.Controllers.ApiDevToolController
GetPageIds on type BlexzWeb.Controllers.ApiDevToolController

The WebApiConfig.cs are like bellow:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        //code bellow used to return json on api call
        GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings
            .Add(new System.Net.Http.Formatting.RequestHeaderMapping("Accept",
                 "text/html",
                 StringComparison.InvariantCultureIgnoreCase,
                 true,
                 "application/json"));
    }
}

Controller code:

public class ApiDevToolController : ApiController
{
    private bool IsValid { get; set; }

    [HttpGet]
    public IHttpActionResult IsStoreKeyValid(string storeName, string storeKey)
    {
    }

    //get list of pageids
    [HttpGet]
    public IHttpActionResult GetPageIds(string storeName, string storeKey)
    {
    }
}

Url I am using to hit controller: http://localhost:49817/api/apidevtool/isstorekeyvalid?storeName=test.myblexz.com&storeKey=fdesfhkfg5g437dfgh5u

Whats wrong I am doing here? Any idea how to fix it?

Upvotes: 3

Views: 844

Answers (2)

D-Shih
D-Shih

Reputation: 46229

Let us see the source code from webapi ApiControllerActionSelector code of action selector.

private List<CandidateActionWithParams> FindMatchingActions(HttpControllerContext controllerContext, bool ignoreVerbs = false)
{
    // If matched with direct route?
    IHttpRouteData routeData = controllerContext.RouteData;
    IEnumerable<IHttpRouteData> subRoutes = routeData.GetSubRoutes();

    IEnumerable<CandidateActionWithParams> actionsWithParameters = (subRoutes == null) ? 
        GetInitialCandidateWithParameterListForRegularRoutes(controllerContext, ignoreVerbs) :
        GetInitialCandidateWithParameterListForDirectRoutes(controllerContext, subRoutes, ignoreVerbs);

    // Make sure the action parameter matches the route and query parameters.
    List<CandidateActionWithParams> actionsFoundByParams = FindActionMatchRequiredRouteAndQueryParameters(actionsWithParameters);

    List<CandidateActionWithParams> orderCandidates = RunOrderFilter(actionsFoundByParams);
    List<CandidateActionWithParams> precedenceCandidates = RunPrecedenceFilter(orderCandidates);

    // Overload resolution logic is applied when needed.
    List<CandidateActionWithParams> selectedCandidates = FindActionMatchMostRouteAndQueryParameters(precedenceCandidates);

    return selectedCandidates;
}

We can see if you use register in route for RouteTable, it will find the execute action by your parameters type by defualt.

I would use RoutePrefix and Route attribute to set the route config for web api.

[RoutePrefix("api/ApiDevTool")]
public class ApiDevToolController : ApiController
{
    private bool IsValid { get; set; }

    [HttpGet]
    [Route("IsStoreKeyValid")]
    public string IsStoreKeyValid(string storeName, string storeKey)
    {

    }

    //get list of pageids
    [HttpGet]
    [Route("GetPageIds")]
    public string GetPageIds(string storeName, string storeKey)
    {

    }
}

Upvotes: 1

Mangesh Auti
Mangesh Auti

Reputation: 1153

It happens because your second action name starts with Get... and also it has the same parameter like first action (IsStoreKeyValid(string storeName, string storeKey))

By default, if action is HttpGet then it searches action name which starts with GetSomething and check parameter. More Info MSDN

You need to change the second function name or need to use attribute routing

ex.[Route("pageIds")]

more info attribute routing

Upvotes: 1

Related Questions