Search code examples
c#asp.net-coreasp.net-core-mvcurl-routing

Cannot get LinkGenerator to create a path to API action


I am trying to create a link to an API endpoint from inside a Service - outside of a Controller.

Here is the Controller and its base class. I am using API versioning and Areas in ASP.NET Core.

[ApiController]
[Area("api")]
[Route("[area]/[controller]")]
public abstract class APIControllerBase : ControllerBase
{

}

[ApiVersion("1.0")]
public class WidgetsController : APIControllerBase
{
    [HttpGet("{id}"]
    [Produces("application/json")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<ActionResult<Widget>> Get(Guid id)
    {
        // Action...
    }
}

API Versioning configuration:

services.AddApiVersioning(options =>
{
    options.ApiVersionReader = ApiVersionReader.Combine(
        new QueryStringApiVersionReader
        {
            ParameterNames = { "api-version", "apiVersion" }
        },
        new HeaderApiVersionReader
        {
            HeaderNames = { "api-version", "apiVersion" }
        });
});

And where I actually try to use LinkGenerator:

_linkGenerator.GetPathByAction(
    _accessor.HttpContext,
    action: "Get",
    controller: "Widgets",
    values: new
    {
        id = widget.Id,
        apiVersion = "1.0"
    }
)

I've tried all manner of variations for the LinkGenerator. I've used the HttpContext overload, I've used the overload without it, I've included the apiVersion parameter and omitted it, I've removed [ApiVersion] from the Controller entirely. Everything always comes back null. If I route to a normal MVC Controller like GetPathByAction("Index", "Home") I get a URL like I should though, so I'm think it must be related to my API Areas, or versioning setup.


Solution

  • You're not specifying the area:

    _linkGenerator.GetPathByAction(
        _accessor.HttpContext,
        action: "Get",
        controller: "Widgets",
        values: new
        {
            area = "api",
            id = widget.Id,
            apiVersion = "1.0"
        }
    )