Injecting UrlHelper in ASP.NET Core MVC

One of our APIs has a dynamic routing system that invokes a different handler based on attributes of the incoming HTTP request.

Each of these handlers is responsible for building the API response which includes generating hypermedia links that describe the state and capabilities of the resource, for example:

  "total_count": 3,
  "limit": 10,
  "from": "2018-01-25T06:36:08Z",
  "to": "2018-03-10T07:13:24Z",
  "data": [
      "event_id": "evt_b7ykb47ryaouznsbmbn7ul4uai",
      "event_type": "payment.declined",
      "created_on": "2018-03-10T07:13:24Z",
      "_links": {
        "self": {
          "href": ""
        "webhooks-retry": {
          "href": ""

To avoid hardcoding paths into these handlers we wanted to take advantage of UrlHelper to build the links. Unlike many components in ASP.NET Core, this is not something that is injectable by default.

To register it with the built-in container, add the following to your Startup class:

services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
services.AddScoped<IUrlHelper>(x => {
    var actionContext = x.GetRequiredService<IActionContextAccessor>().ActionContext;
    var factory = x.GetRequiredService<IUrlHelperFactory>();
    return factory.GetUrlHelper(actionContext);

Both IActionContextAccessor and IUrlHelperFactory live in the Microsoft.AspNetCore.Mvc.Core package. If you're using the Microsoft.AspNetCore.All metapackage you should have this referenced already.

Once done, you'll be able to use IUrlHelper in any of your components, assuming you're in the context of a HTTP request:

if (authResponse.ThreeDsSessionId.HasValue)
    return new PaymentAcceptedResponse
        Id = id,
        Reference = paymentRequest.Reference,
        Status = authResponse.Status
    .WithLink("self", _urlHelper.PaymentLink(id))
        _urlHelper.Link("AcsRedirect", new { id = authResponse.ThreeDsSessionId }));

Ben Foster

About Me

I'm a software engineer and aspiring entrepreneur with 12+ years experience in the tech industry and have worked with startups and SMB’s in areas such as healthcare, recruitment and e-commerce (I even worked in enterprise, once). I founded my first startup Fabrik in 2011.

I now head up the engineering team at Checkout. If you're interested in working in an exciting and innovative fin-tech company, drop me a message.

Creative Commons Licence