Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 274
Valuator Avatar asked Jan 26 '23 15:01

Valuator


2 Answers

You're not specifying the area:

_linkGenerator.GetPathByAction(
    _accessor.HttpContext,
    action: "Get",
    controller: "Widgets",
    values: new
    {
        area = "api",
        id = widget.Id,
        apiVersion = "1.0"
    }
)
like image 56
Chris Pratt Avatar answered Jan 31 '23 05:01

Chris Pratt


In case it helps someone else, I had an issue very similar to this but the action was named GetAsync and it turns out you cannot reference the action by it's full name "GetAsync", you have to use it without the suffix so just "Get".

like image 20
alastairtree Avatar answered Jan 31 '23 03:01

alastairtree