What's new in Razor v2

I know, it’s been too long since I blogged, and I won’t even bother saying I’ll try to blog more (though I will) because hopefully you’ll see that for yourself. A lot has happened since I last blogged but the biggest thing is that the ASP.Net Web Stack (which is what we call the out-of-band stuff we ship, like MVC, WebPages, WebAPI and Razor) is now truly an open-source project! We’re hosted on CodePlex (http://aspnetwebstack.codeplex.com/) and if you want more details, check out Scott Hanselman’s awesome post about it.

Now that we’re open, I’ll be able to start talking a little more directly about what we’re doing. It’s very exciting for us, and to alleviate your worries that open-source means Microsoft isn’t working on it anymore, we’re still working full-time on our current release and even starting a bit of planning for v.Next.

All that aside, we also released a new version of Razor since I’ve blogged and I thought I’d give you a quick run-through of the features. In later posts, I’ll go over the details of what’s changed as well as some new information for those hosting Razor outside of ASP.Net on how to take advantage of those features.

~/ – Url resolution made easy, goodbye @Href/@Url.Content!

One of the most common patterns in MVC Views is this:

<script src=”@Url.Content(“~/Scripts/myscript.js”)”></script>

Well, in Razor v2, you can express the same intent with much less code, and it looks much cleaner too:

<script src=”~/Scripts/myscript.js”></script>

Note the lack of any code transitions! How does this work? It’s quite a simple algorithm: Whenever we see an attribute value that starts “~/”, we treat it like a URL and replace it with a call to @Href (in WebPages) or @Url.Content (in MVC). Note that this is ANY attribute, so if you typed the following:

<div class=”~/Foo”>

We’ll treat “~/Foo” as a URL. We made this choice because we didn’t want to limit you to a list of attributes that we think have URLs. Especially when you might want to put URLs in a data- attribute. Imagine using a data- attribute to tell your client-side javascript what the root of your application is:

<html data-root=”~/”>

Then you can use jQuery to access this data: $(document).data(‘root’) and use it when making Ajax calls to make sure your app is portable even if it’s in a sub-folder.

What if you want to inject code snippets in to your URL? Well that’s easy, just treat it like you would if you were injecting code in to other attribute values:

<a href=”~/MySite/@Foo/Bar/@Baz”>Something!</a>

I should note that we’re actually not doing much special here, the code above is equivalent to the following MVC code in Razor v1:

<a href=”@Url.Content(“~/MySite/”)@Foo/Bar/@Baz”>Something!</a>

So we are just resolving that first portion of the URL and then going back to regular string concatenation for the rest.

Conditional Attributes

The other major feature (there are a few others I’ll go over in later posts but they are smaller) is Conditional Attributes. I’ll freely admit we borrowed this feature heavily from the fantastic Spark View Engine written by our very own Louis Dejardins.

Have you ever typed code like this in Razor v1?

@{ var cls = GetClass(); }
<div id=”foo”@if(cls != null) { <text>class = “@cls”</text> }>

If not, let me explain why you’d want to do this. In Razor v1, null was treated the same as an empty string so if you were to have code like this:

<div id=”foo” class=”@cls”>

Then if cls was null, we’d render

<div id=”foo” class=””>

Eugh! That looks ugly! In Razor v2, the same code would render this:

<div id=”foo”>

Note the missing class attribute? We’ve even taken away the leading space! Another feature of this is that we’ll also collapse whitespace within the attribute value:

@{ string foo = null; string bar = “bar” }
<div id=”foo” class=”@foo @bar”>


<div id=”foo” class=”bar”>

We also special case boolean values. If the expression evaluates to false, we treat it the same as null. If it evaluates to true, we render out the attribute name again. This allows you to write code like the following for checkboxes:

<input type=”checkbox” checked=”@isChecked”>

If isChecked is true, we render checked=”checked”, if it’s false, we don’t render the checked attribute at all.

Finally, we do NOT treat String.Empty ("") like null in this case. If the expression evaluates to an empty string, we WILL render the attribute:

@{ var foo = ""; }
<div class=”@foo”>


<div class=””>

The reason for this lies in the difference between null and String.Empty. Null indicates the complete absence of a value, whereas String.Empty is a value, a string of length 0.

In the currently released (Beta) version of Razor, we do this for all attributes. However, in the next release (and, in fact, in the live code on CodePlex) we have entirely disabled the conditional attributes feature for data- attributes. You'll still get the ~/ URL resolution, but we won't remove null values or do fancy tricks with booleans in data- attributes. This was done because those attributes are usually read from JavaScript, so the semantics are different and we wanted to give you full control.

There’s much more!

That’s just a quick summary. I’ll be publishing another post soon with even more new features. Then, we’ll go in to how Conditional Attributes is implemented and how you can make sure your custom Razor hosts support this feature.

Please don’t hesitate to let me know what you think in the comments!