tl;dr Summary

Image links in the Razor view engine in ASP.NET MVC allow you to do magical things with image links.

The new magical syntax is as follows:

This post was mostly stolen from the StackOverflow question http://stackoverflow.com/questions/5331777.

Introducing the problem

Let’s say you need to add a dog image to your website product. Like, say:

dog

Pretty good, right? I’d say. I’m not saying I made it or anything, but if I had, I would be proud to say I did, it’s solid artwork.

Anyway, you have this (really excellent, well-crafted) file named dog.png. So far, so good. Now you just need to link that image from your ASP.NET MVC website.

First, we dump it in the project folder structure:

Now all we have to do is reference it from our Razor view.

At this point you’re presented with a dilemma.

The dilemma: how do I reference image files in my project again?

 

We’ll explore all the common solutions below.

The F Minus solution

Works on my machine, right? Ok, I don’t think people do this even on accident anymore. But I wanted to include this example for completeness, when we compare the “bad” answer versus the “good” answer. For the record, this is the bad answer. This. Everything else is great, compared to this.

 

With that said, there are other, far more common, wrong answers.

The absolutely wrong answer, and the relatively wrong answer

There are two common ways to go wrong linking images: use absolute paths, or use relative paths.

 

I won’t go too hard on either approach above, because ultimately if you don’t have broken image links, you’re fine. But you’ll break something eventually. Probably. I mean, most of the time you can get away with an absolute path, let’s be honest here.

With that said, there’s a low effort solution that everyone should use anyway.

The right answer: ~/ and Url.Content(“~/”)

So, not to spoil the ending, but to reliably build out image URLs in Razor, just add ~/ to the src attribute of your image tag. And for background images you link from stylesheets (also known as cascading CSS stylesheets sheets s sheets PIN number), use an longer-syntax-but-equally-effective Url.Content(“~/”) call.

You can do something similar with script tags

My exhaustive research has turned up a post explaining that this ~/ relative path helper can also be used on <script> tags.

Razor syntax versioning agnosticism

While attempting to figure out when this “~/” syntax was introduced, I came to the conclusion that the truth is unknowable, or at least not within 5 minutes of searching. I feel in my heart this syntax was (will be?) introduced in ASP.NET MVC 5, but again, there’s no true way to know for sure*.
* not actually true

This blog post was harvested from my monopoly-dotnet sample MVC project

I’ve put together a sample ASP.NET MVC 5 project implementing a portion of Monopoly, You may find browsing the source illuminating. I wrote the project to to explore ASP.NET MVC 5, automated web testing, singleton abuse, basic EF 6, and a few other things.

Get the source (or browse the source online): https://github.com/pseale/monopoly-dotnet