简体   繁体   中英

Multiple actions were found that match the request in Web Api using Attribute Routing

Out of curiosity, I was trying to build API with the number of overloads.

Initially, I was getting the below error

- Multiple actions were found that match the request in Web Api

But again, I wanted to give some try in other way opposed to mentioned in the above link.

I went ahead & decorated my API with [Route] & here is how my API looks like.

namespace CTB_APP.Controllers.API.Delete
{
[RoutePrefix("api/test/")]
public class TestController : ApiController
{
    [Route("name")]
    public string Get(string param)
    {
        return param + 1;
    }

    [Route("age")]
    public int Get(int param)
    {
        return param + 1;
    }
  }
}

I was thinking that the above the API could be easily served at the respective endpoints.

http://localhost:51370/api/test/name?param=Chetan

http://localhost:51370/api/test/age?param=28

But this is returning the below error.

{ "Message": "No HTTP resource was found that matches the request URI ' http://localhost:51370/api/test/age?param=28 '.", "MessageDetail": "No action was found on the controller 'Test' that matches the name 'age'." }

Please note Attribute routing is enabled.

WebAPIConfig.cs

config.MapHttpAttributeRoutes();
        config.Routes.MapHttpRoute(
            name: "ApiByAction",
            routeTemplate: "api/{controller}/{action}",
            defaults: new { action = "Get" }
        );


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

How can I fix this??

Thanks.

When I tested it I instinctively removed the additional slash / from the route prefix and it worked.

Your problem therefore is that you have an addition slash in the route prefix, which i believe is not allowed.

[RoutePrefix("api/test/")]

causes the following error

"The route prefix api/test/ on the controller named Test cannot end with a / character"

Remove the slash at the end of the route template

[RoutePrefix("api/test")]

The following in-memory test was used to verify the expected behavior

[TestClass]
public class MyTestClass {
    [Test]
    public async Task __WebApi_Should_Match_Route() {
        //Arrange
        var config = new HttpConfiguration();
        config.MapHttpAttributeRoutes();
        var httpServer = new HttpServer(config);
        var client = new HttpClient(httpServer);

        //Act
        var response = await client.GetAsync("http://localhost/api/test/age?param=28");
        var returnJson = await response.Content.ReadAsStringAsync();

        //Assert
        response.IsSuccessStatusCode.Should().BeTrue();

        var result = JsonConvert.DeserializeObject<int>(returnJson);
        result.Should().Be(29);
    }
}



[RoutePrefix("api/test")]
public class TestController : ApiController {
    [Route("name")]
    public string Get(string param) {
        return param + 1;
    }

    [Route("age")]
    public int Get(int param) {
        return param + 1;
    }
}

Also ensure that attribute routing must be enabled before convention-based routes

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

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

Reference Attribute Routing in ASP.NET Web API 2

It looks as if you've not told the route itself to expect a parameter, try registering your attributes for your routes as:

[Route("name/{param=param}")]

And if that doesn't work try:

[HttpGet, Route("name/{param=param}")]

Related Stackoverflow Q

namespace CTB_APP.Controllers.API.Delete
{
[RoutePrefix("api/test/")]
public class TestController : ApiController
{
    [Route("name/{param}")]
    public string Get(string param)
    {
    return param + 1;
    }

   [Route("age/{param}")]
   public int Get(int param)
   {
      return param + 1;
   }
 }
}

End Point 1: http://localhost:51370/api/test/name/mm End Point 2: http://localhost:51370/api/test/age/9

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM