How to add the slug to all Link generation in an asp.net core website?
Binding IUrlHelper
directly has no effect, as MVC internally resolves the instance using a factory. To get an instance of your own custom URL helper in your controllers and razor views, you need to provide a custom implementation of IUrlHelperFactory
in your startup class.
The following code snippets allow you to decorate the original URL helper with your own functionality:
In your Startup
class, you need to add the custom implementation for IUrlHelperFactory
with singleton scope after AddMvc
:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddSingleton<IUrlHelperFactory, CustomUrlHelperFactory>();
}
And the custom implementation could look like this:
public class CustomUrlHelper : IUrlHelper
{
private IUrlHelper _originalUrlHelper;
public ActionContext ActionContext { get; private set; }
public CustomUrlHelper(ActionContext actionContext, IUrlHelper originalUrlHelper)
{
this.ActionContext = actionContext;
this._originalUrlHelper = originalUrlHelper;
}
public string Action(UrlActionContext urlActionContext)
{
return _originalUrlHelper.Action(urlActionContext);
}
public string Content(string contentPath)
{
return _originalUrlHelper.Content(contentPath);
}
public bool IsLocalUrl(string url)
{
return _originalUrlHelper.IsLocalUrl(url);
}
public string Link(string routeName, object values)
{
return _originalUrlHelper.Link(routeName, values);
}
public string RouteUrl(UrlRouteContext routeContext)
{
return _originalUrlHelper.RouteUrl(routeContext);
}
}
public class CustomUrlHelperFactory : IUrlHelperFactory
{
public IUrlHelper GetUrlHelper(ActionContext context)
{
var originalUrlHelperFactory = new UrlHelperFactory();
var originalUrlHelper = originalUrlHelperFactory.GetUrlHelper(context);
return new CustomUrlHelper(context, originalUrlHelper);
}
}
The IUrlHelper is not injectable by default.
You will have to modify your startup.cs code a bit as explained in this blog.
You will have to first register IActionContextAccessor.
Then with the help of UrlHelperFactory, you can inject your custom implementation as shown below:
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.
This should help you to resolve your problem.