Category Archives: ASP.NET Core

Back to the Future with a Tag Helper

In October, I gave a presentation to the .NET DC User Group on the night before Marty McFly was due to arrive in 2015 according to the movie Back to the Future Part 2.  This was a great opportunity for me to put together a simple demo that I could run with ASP.NET 5 and show something easy to digest.  In this case, I put together an HTML version of the time circuits from Doc’s Delorean time machine.

That’s easy… a set of date displays on a grey background.  I broke out a copy of Visual Studio 2015 and set to work making one row work in CSS and HTML. Continue reading

Customize ASP.NET MVC 6 View Location Easily

In continuing to explore and document the cool new features of ASP.NET 5 and MVC 6, I stumbled across an interesting question from my friend Josh on Slack: how do I customize the razor view engine in ASP.NET 5 so that I can rename that Shared folder to _Shared?  I knew I had seen this feature somewhere before and started digging.

MVC 6 Solution Explorer

MVC 6 Solution Explorer

The reasoning behind this change is quite simple, and one that I’m ashamed wasn’t implemented in the default templates:  Shared is a “magic folder” that all Views in an MVC project can reference contents out of.  As such, it should have special placement or be easy to find in the solution explorer.  The simple solution is to prefix Shared with an underscore so that it is always at the top of the folder list.  Brilliant!

In previous versions of ASP.NET MVC, we could subclass the RazorViewEngine to make it do tricky things with determining where and how to find and implement view files.  Fun, but that’s just too complicated for just wanting to rename a folder.  I want to find a simple configuration option that I can set to update the behavior of the view engine.

Introducing the IViewLocationExpander

In MVC 6, there is a new interface available called IViewLocationExpander that contains two methods to help define how the Razor view engine will locate and cache the view files that it finds.  There are two methods in this interface that are trivial to implement:

  • PopulateValues – this method is passed the context of the current view location when a view is requested.  You can modify the context or add values appropriately to indicate if there is a change since the last time the view was requested.
  • ExpandViewLocations – this method is called when the RazorViewEngine wants to determine the list of potential locations for a view.  The second argument on this method is the list of current paths that will be searched for views.

That’s all I need to make my quick swap / rename of the Shared folder.  I wrote a simple class to do this remapping for me:

That’s a very standardLinq select statement to do a string replace. The code to add this to our ASP.NET pipeline is easy, andcan be done with some dependency injection trickery in the Startup.ConfigureServices class:

Sweet… now MVC will look in all of the standard locations, and because I added this ViewLocationExpander to the collection it will update the existing view locations without disturbing them. I could have cleared and added just this one Expander with a whole different set of locations to search, but that would be a bit of overkill for this problem I wanted to solve.

Summary

A simple rename of a magic folder can be accomplished by adding configuration to MVC.  Not bad, and something that was handled with a new configuration option in the ASP.NET pipeline.  Big thanks to Imran Baloch whose blog post on ViewLocationExpanders answered some of my questions about how to implement this feature.

ASP.NET Tag Helpers – Making HTML More Cool!

I’ve been at the AngleBrackets conference this week giving several talks and hanging out with the ASP.NET team members at the event.  We’ve had several great conversations about the new ASP.NET Tag Helpers functionality in the just announced ASP.NET 5 release.  That version is just in beta at this point, but we’re already contributing and getting great feedback on the direction for the framework. Continue reading