Category Archives: .Net

Authoring ASP.NET 5 Tag Helpers

One of the biggest updates to Razor views in ASP.Net 5 (MVC 6) is TagHelpers. TagHelpers by and large replace HTML Helpers for generating snippets of dynamic HTML.

Why HTML Helpers are Being Replaced

HTML Helpers were helpful in that they gave you a way to generate HTML from strongly typed models, but they did it in a way that couldn’t take advantage of the rich HTML editor in Visual studio. For example to generate an link to your homepage with a CSS class you would write something like this:

@Html.ActionLink("About Me", "About", "Home", null, new { @class="btn btn-primary" })

Because the class is declared inside a C# method your editor can’t help you with CSS class intellisense. Furthermore, it’s a clumsy syntax that isn’t immediately obvious.

TagHelpers provide a more HTML native way to generate tags, while providing even greater support for strongly-typed views. A TagHelper implementation of the above example would look like:

<a asp-controller="Home" asp-action="About" class="btn btn-primary">About Me</a>

HTML Helpers are still available in ASP.Net 5 for backwards compatibility, but new views will benefit from TagHelpers.

Authoring a Gravatar TagHelper

The rest of this blog post will be about implementing a custom TagHelper to display a Gravatar profile picture. Gravatar is a service that hosts profile pictures that can be used across third-party websites. Those websites can display a profile image by computing an MD5 hash of the user’s email address. For example my email is pnewhook@infusion.com, which can be turned into the profile image found at http://www.gravatar.com/avatar/fae2af75c8c0ca925a229678b528bb04.

First you’ll need the latest version of Visual Studio 2015, or the command line tools found at the ASP.Net Home GitHub repository.

Defining the TagHelper

TagHelpers are C# classes that inherit from the abstract Microsoft.AspNet.Razor.Runtime.TagHelpers.TagHelper class, which is in the Microsoft.AspNet.Mvc.Razor assembly available on NuGet.You can implement a TagHelper in a class inside your ASP.Net 5 project, or in another assembly.

We also want to add the TargetElement attrubte to tell Razor which HTML tag this TagHelper applies to. We’re going to target the plain <img> tag, though we could just as easily create a custom tag. Furthermore, we want Razor to ignore regular <img> elements. We can do this by specifying the optional Attributes parameter in the TargetElement attribute. In my case I’ve specified my Gravatar tags will have a gravatar-email attribute. Our new class will look something like this.

[TargetElement("img", Attributes="gravatar-email")]
public class GravatarTagHelper : TagHelper
{

}

A note about naming conventions

You may have noticed that the TagHelpers that ship with MVC use an asp- prefix for attributes. That was purely a design choice by the ASP.Net team to differentiate TagHelper attributes from normal attributes. Native attributes that supplement native HTML tags (<a>, <link>, <input>) will be prefixed with asp- whereas attributes on custom TagHelpers (<cache>) won’t be prefixed.
In you own TagHelpers you’re free to prefix as you choose, though the prefixs for augmentative attributes is a good pattern to follow.

Getting Inputs from HTML Attributes

The easiest way to read from the HTML attribute is to use the HtmlAttributeName attribute. This will cause the value of the HTML attribute to be assigned to the property.

[TargetElement("img", Attributes=EmailAttributeName)]
public class GravatarTagHelper : TagHelper
{
    // the name of attribute has been moved to a variable to keep things DRY
    private const string EmailAttributeName="gravatar-email";
     
    [HtmlAttributeName(EmailAttributeName)]
    public string EmailAddress { get; set; }
}

Generating the Profile Hash

TagHelper defines a pair or methods that are used to turn the input into HTML: Process and ProcessAsync. Since we’re not dependent on any asynchronous calls, we’ll use the synchronous version, but it’s helpful that ASP.Net 5 Razor views can now call async methods.

Both process methods take two parameters, a TagHeplerContext and a TagHelperOutput. TagHelperContext is only necessary if you need the HTML that is generated between your TagHelper opening and closing tags. Our GravatarTagHelper doesn’t include any child content, so we won’t use the context parameter.

The TagHelperOutput will be what’s ultimately turned into an HTML tag. It has a number of properties that are assigned in your Process method That will be used to generate the HTML output. It may be a little odd to see TagHelperOutput as a paramater and not a return value, but designing it this way lets TagHelpers be chained together.

The contents of our Process method are mostly Gravatar specific. The email address property, which is set above, is converted to an MD5 hash string. If you’re following along, make sure you include System.Security.Cryptography.Hashing in your project.json. The TagHelper specific bit of code is setting the output.Attributes["src"] value. This value becomes the src attribute on the resultant img tag.

public override void Process(TagHelperContext context, TagHelperOutput output)
{
	using(var md5 = MD5.Create())
    {                
        byte[] hash = md5.ComputeHash(Encoding.UTF8.GetBytes(EmailAddress));
        
        // Build the final string by converting each byte
        // into hex and appending it to a StringBuilder
        StringBuilder sb = new StringBuilder();
        for (int i=0;i<hash.Length;i++)
        {
            sb.Append(hash[i].ToString("x2"));
        }
        output.Attributes["src"] ="http://www.gravatar.com/avatar/" +  sb.ToString();
    }
}

Using your TagHelper

If you defined your TagHelper in a separate project from you web application you will need to do two things. First, reference your TagHelper project in the web project project.json.

Secondly you’ll need to import the TagHelper. This is done using the @addTagHelper directive in the _GlobalImport.cshtml. _GlobalImport.cshtml is a new file for MVC projects that lets you import directives into all your Razor views.

Now I can add a TagHelper to my Razor view with the following code:

<img gravatar-email="pnewhook@infusion.com">

And Razor will output the following HTML

<img src="http://www.gravatar.com/avatar/fae2af75c8c0ca925a229678b528bb04">

Conclusion

The biggest improvement to the Razor view engine in ASP.Net 5 is TagHelers. TagHelpers make it easy create reusable HTML snippets that can be shared across projects. TagHelers replace HTML Helpers with HTML native syntax, while still supporting strongly-typed views.

If TagHelpers seem similar to Angular directives, it’s not by accident. The ASP.Net team has said they were heavily influenced by directives, albeit in a server-side environment.

I you want to see a full implementation of a Gravatar TagHelper, or want something to use in your web sites, check out my gravatar-taghelper project on GitHub.

Getting Started with ASP.Net 5 Nightly Builds on Windows

ASP.Net 5 is more than an update to ASP.Net, it is a dramatic rethinking of the .Net web stack. By dropping some of the baggage that has been with the framework since classic ASP, Microsoft has been able to greatly reduce the footprint of an ASP.Net application and created a more modular runtime that can be deployed to Windows, Mac, and Linux.

If you’d like to read a more complete breakdown of new features, Scott Guthrie’s excellent post announcing ASP.Net 5 is a good starting place.

As of April 2015, ASP.Net 5 is still in the beta. The easiest way to use it is to install the latest Visual Studio 2015 Community Technology Preview. But if you want to get features as the come available the best option is to install the new cross platform command line tools. These are the instructions for installing the latest ASP.Net tooling on Windows.

Installing dnvm

Because Visual Studio doesn’t run on Mac or Linux, a new set of tools needed to be created to use ASP.Net on those platforms. The ASP.Net team have been building a set of command line applications that lets users build ASP.Net projects with any editor.

ASP.Net 5 includes a new execution environment is called DNX. DNX bootstraps and runs your application, however it is not the CLR itself.

To install DNX you will need DNVM, the Dot Net Version Manager. You can download DNVM from the aspnet/home GitHub repo. This repo contains tools and samples to get you started, though some of the instructions don’t necessarily reflect the latest rapidly changes to the framework.

You will install DNVM by running the following in a command prompt.

@powershell -NoProfile -ExecutionPolicy unrestricted -Command "&{$Branch='dev';iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.ps1'))}"

This script will create a new .dnx directory under your %USERPROFILE%. It will contain a bin directory with the dnvm command.

Note: Originally the new ASP.Net runtime was code-named Project-K, so you may see references to tools that begin with the letter k (k, kvm, kpm). Those tools have been replaced by their DNX counterparts.

Adding DNX Nightly Builds NuGet Feed

You now have DNVM installed, but if you can’t yet install the latest nightly builds. The DNX is delivered as NuGet packages, and the nightly builds are served from a custom NuGet feed, https://www.myget.org/F/aspnetvnext/api/v2/. To add this feed to NuGet open %AppData%/NuGet/NuGet.config and change the contents to the following.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="AspNetVNext" value="https://www.myget.org/F/aspnetvnext/api/v2/" />
    <add key="nuget.org" value="https://www.nuget.org/api/v2/" />
  </packageSources>
  <disabledPackageSources />
  <activePackageSource>
    <add key="nuget.org" value="https://www.nuget.org/api/v2/" />
  </activePackageSource>
</configuration>

Installing the .Net Execution Environment (DNX)

Now that you have DNVM and you’ve configured NuGet you can install the DNX. To install the latest version open PowerShell or a command prompt and run:

dnvm upgrade

This will install a new runtime under %USERPROFILE%/.dnx/runtimes/ and add the bin directory of the new runtime to your PATH. The bin directory has two important commands

  • dnx – used run a .Net application under the DNX
  • dnu – Dot Net Utility used to perform tasks like building, installing packages, and more

Running a Sample Project

You should now be ready to run a sample project. New project scaffolding isn’t functional with DNX at the moment, so the best way to run an ASP.Net 5 project is to clone an existing project. The aspnet/home repo mentioned above has sample projects using the latest runtime, just make sure you’re looking in the dev branch.

The critial component to look for is the supported frameworks in the project.json file. The supported frameworks should be dnx451 and dnxcore50.

{
//...
"frameworks": {
"dnx451": { },
"dnxcore50": { }
}
}

If you see aspnet50 or aspnetcore50 you’re looking at an old version from before the DNX rename.

So, clone the dev branch of the aspnet/home repo.Then, at the command line move to the HelloMvc folder and run the following command.

dnu restore

This is equivalent to restoring packages for a solution with NuGet in Visual Studio. In fact, under the covers it’s simply using the newest version of NuGet!

Now you’re ready to run the project. Still at the root of the HelloMvc folder simply run dnx . web and your project will begin running at http://localhost:5001 (as defined in the project.json).

D:\dev\aspnet-home\samples\HelloMvc> dnx . web
Started

The output for the web command is pretty underwhelming. If you’d like to see a little more output upgrade Microsoft.AspNet.Server.WebListener in project.json to 1.0.0-beta5* and you’ll see something like the following.

D:\dev\uavdb\src> dnx . web
info : [Microsoft.Framework.DependencyInjection.DataProtectionServices] Userprofile is available. Using 'C:\Users\pnewhook\AppData\Local\ASP.NET\DataProtec
ion-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
info : [Microsoft.Net.Http.Server.WebListener] Start
info : [Microsoft.Net.Http.Server.WebListener] Listening on prefix: http://lcalhost:5001/
Started

Conclusion

It’s an exciting time to be an .Net developer. The latest version of ASP.Net framework is open source and it’s possible to follow the team’s development live. While you could install the latest Visual Studio 2015 CTP, you won’t be able to try new features as they’re released. There will likely be a big announcement at Build on April 29th. The command line tools are probably the way to go for now, and they have the added bonus of working cross platform.

There are three commands you’ll run into:

  • dnvm – the .Net Version Mananger for installing the DNX
  • dnu – the .Net Utility for managing projects and packages
  • dnx – the Execution Environment executable for running your projects

A core tenent of the DNX is to make everything a NuGet package. While the framework is under development, and potentially beyond, nightly builds are served through a MyGet feed that needs to be configured in your NuGet install.

After you’ve taken these steps you’ll be ready to experiment with ASP.Net 5 feature hot off the press.