eoldre
eoldre

Reputation: 1087

Controller dependency injection from route parameter

I'm using attribute base routing in an ASP.Net Core 2 application and attempting to inject a parameter into a Controller based on the route.

When I use the example I get an exception with message: "Unable to resolve service for type 'System.String' while attempting to activate (My Controller type)"

[Route("api/agencies/{agencyId}/clients")]
public class ClientDataController : Controller
{
    public ClientDataController([FromRoute] string agencyId)
    {

    }

    [HttpGet]
    public void SomeAction()
    {
    }

}

Are you not able to use the FromRoute attribute in a controller constructor? Do I have something else obviously wrong?

Upvotes: 7

Views: 2366

Answers (2)

JG3
JG3

Reputation: 53

FromRoute only works on action level not on controller level.

One way of getting a route parameter in a constructor is to pass an IHttpContextAccessor to the constructor and then use the GetRouteValue method on the actual HttpContext to get the parameter value

[Route("api/agencies/{agencyId}/clients")]
public class ClientDataController : Controller
{
    private readonly agencyId;

    public ClientDataController(IHttpContextAccessor httpContextAccessor)
    {
        agencyId = (string)httpContextAccessor.HttpContext.GetRouteValue("agencyId");
    }

    [HttpGet]
    public void SomeAction()
    {
     //use agencyId here
    }

}

Upvotes: 0

Ripal Barot
Ripal Barot

Reputation: 716

There is a way to insert the value from the class Route attribute. Use property instead of the constructor.

The Route attribute can be applied only to class and method. See the source code here. The FromRoute can be applied to parameters and properties. See code here.

Since the Route attribute is not applicable to the constructor, the DI will not be able to resolve the parameter and you will get an error.

On the class level, we can use the FromRoute on public property to fetch the value from the Route.

[Route("api/agencies/{agencyId}/clients")]
public class ClientDataController
{
    [FromRoute]
    public string agencyId { get; set; }

    [HttpGet]
    public string SomeAction()
    {
        return agencyId;
    }

}

Upvotes: 2

Related Questions