ASP.NET MVC Core IUrlHelper: Convert Your UrlHelper Extensions
When converting your MVC application over to MVC Core, you want to reuse as much as possible. Today, I show you a simple little trick on how to continue using your existing URLHelpers in ASP.NET MVC Core.
Almost 10 years ago, ASP.NET MVC was introduced and developers started learning a new way to maximize web development using something other than Web Forms.
Ten years later, We are now introduced to ASP.NET Core along with a new MVC.
Essentially, the methodology is the same, but we have new plumbing in the system.
ASP.NET was completely rewritten from the ground up.
Things like everything being dependency injected, a new way to configure your application called Middleware, and TagHelpers to remove those pesky HtmlHelpers.
So after building a couple TagHelpers and tinkering with some custom Middleware almost a year ago, I thought this would be a great time to continue learning about ASP.NET MVC Core and truly how different it is compared to the earlier versions.
I started with something simple: UrlHelpers.
It's hardly a collection because it's so application-specific, but I thought it would be easy to move them into MVC Core.
Manage Your Links
When I first started learning about ASP.NET MVC, I was working on a couple of projects and was always using Url.Action() in my Views.
The project had a total of over 50 pages and it continued to grow.
One day, the founder wanted to change the URL and make it more search-engine-friendly.
I had to change over 50 pages of Url.Action() in my Views.
There had to be a better way to build these URLs in every single page.
So I started creating Url Catalogs.
Everything was fine...until ASP.NET MVC Core.
Did Links Just Get Complicated?
I was wondering why my UrlHelper Extension Methods weren't working when I started receiving compiler errors.
After looking around for hints on how to use UrlHelpers in ASP.NET MVC Core controllers, I came across a lot of Stack Overflow entries on creating an IUrlHelperFactory, then the factory would get a UrlHelper, then the UrlHelper would...
Sheesh.
Isn't there just a UrlHelper class anymore?
I know it can be injected, but wow, I just want to piggy-back off an existing UrlHelper.
I looked into the Controller class and yes, there was a Url property type of IUrlHelper.
Solving the problem with One Letter
So basically, I needed to attach my extension methods to a IUrlHelper instead of a UrlHelper.
After digging, I discovered something magical (like unicorns-magical) about extension methods.
You can use extension methods to extend a class or interface
Mind. Blown.
In my catalog of Url Helpers, my extensions went from this:
public static string RootUrl(this UrlHelper helper) { return helper.Content("~/"); }
to this:
public static string RootUrl(this IUrlHelper helper) { return helper.Content("~/"); }
with no issues.
Yeah, I'm completely satisfied with this solution. :-)
With the way I create my ViewModels, I always pass along a ControllerContext which contains the Controller which contains a Url.
As before, I will always have site-wide access to my links.
Conclusion
After playing around with UrlHelpers this weekend, I can finally say I know where to hit now that I've made it out of those weeds.
These UrlHelper catalogs definitely provide an easy (and magic-string free) way to create site-wide links for Views and Controllers.
Stay tuned for more.
Did this make sense? Did you create your Urls a different way? Post your comments below and let's discuss.