0
votes

I am trying to design a API versioning, but I am getting following error

Multiple actions matched. The following actions matched route data and had all constraints satisfied

I didn't want to duplicate all controller methods instead I just override whatever changed but unchanged causes the error. is that bad practice what I am trying? any solution to my problem?

[ApiVersion( "1.0" )]
[AllowAnonymous]
[Route("api/v{api-version:apiVersion}/[controller]")]
public class HeartbeatController : Controller
{
    [AllowAnonymous]
    [HttpGet, MapToApiVersion("1.0")]
    public virtual IActionResult Beat()
    {
        return Ok(DateTime.Now.ToString("HH:mm:ss"));
    }

    [AllowAnonymous]
    [HttpGet, MapToApiVersion("0.9")]
    public virtual IActionResult Get()
    {
        return Ok(Environment.MachineName);
    }
}


[ApiVersion("2.0")]
[AllowAnonymous]
[Route("api/v{api-version:apiVersion}/[controller]")]
public class HeartbeatController : V1.Controllers.HeartbeatController
{
    [AllowAnonymous]
    [HttpGet]
    public override IActionResult Get()
    {
        return Ok("this is version 2 " + Environment.MachineName);
    }
}
1

1 Answers

1
votes

Inheritance can be tricky and it's not always obvious which attributes are inherited and which aren't. In this case, RouteAttribute and HttpGetAttribute are inherited, but ApiVersionAttribute is not.

The following configuration will get you what you're looking for:

using static System.Environment;

[ApiVersion( "1.0" )]
[Route( "api/v{api-version:apiVersion}/[controller]" )]
public class HeartbeatController : Controller
{
    [HttpGet]
    public virtual IActionResult Get() => Ok( MachineName );
}

[ApiVersion( "2.0" )]
public class HeartbeatController : V1.HeartbeatController
{
    public override IActionResult Get() => Ok( "this is version 2 " + MachineName );
}