Displaying Database-stored Images in ASP.NET MVC with Data URLs

I’ve worked on quite a few websites which featured user-uploaded images as part of the content. To implement a feature like this, we obviously have to store the image somewhere. One way to do that is to store all the uploaded images directly in the filesystem, then storing the name of the files for the corresponding record in the database. This has always struck me as a bit clunky, since we’re storing part of the data for a Contact (say) in the database, and part of it on the filesystem. I’d much rather store the image in the database and have everything all in one place.

The problem in a web context is that the normal way of displaying images is to render an <img> tag in the HTML and have the browser make a subsequent request to the server at the URL contained in the tag. If you stored your images in the database, this would mean that you’d need a separate action method that would query the database again and write the image content directly to the response stream. But using an HTML feature called Data URLs, we can actually render the content of the image itself to the markup on the page, and not need to make another server request.

The way to do this is to transform the bytes of your image into a base 64-encoded string, put a special prefix on it, and set that as the value of the src attribute of your <img> element.

So, assuming you had a Entity Framework Contact object that looked like this:

public class Contact
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public byte[] Photo { get; set; }
}

And a view-model like this:

public class ContactViewModel
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string PhotoString { get; set; }
}

You could grab it from the database and send it down to the view like this:

public ActionResult Index(int id)
{
    var c = _contactEntities.Find(id);
    var vm = new ContactViewModel 
                 { 
                     Id = c.Id, 
                     FirstName = c.FirstName, 
                     LastName = c.LastName, 
                     PhotoString = "data:image/png;base64," + Convert.ToBase64String(c.Photo)
                 };
}

And render the view:

@model ContactViewModel;

...

<ul>
    <li>
        <span>First Name:</span> @Model.FirstName
    </li>
    <li>
        <span>Last Name:</span> @Model.LastName
    </li>
    <li>
        <span>Photo:</span> <img src="@Model.PhotoString" />
    </li>
</ul>

Keep in mind that this will increase the download size of your page, so you’ll have to weigh that against the convenience of storing images in the database. Also be aware that this won’t work in IE 7 and below, and data URLs are limited to 32k in IE 8. For more info, see the wikipedia article on Data URIs.

3 thoughts on “Displaying Database-stored Images in ASP.NET MVC with Data URLs

  1. Jonas

    Thanx.
    Your code:
    PhotoString = “data:image/png;base64,” + Convert.ToBase64String(c.Photo);
    saved me :)

  2. alex

    Perfeito…. funcionou muito bem aqui e achei que este metodo de fazer, é o mais facil. muito bom valeu!!!!

  3. Paulo

    I didn’t know about data:image/png;base64," + Convert.ToBase64String(c.Photo)
    Thank you man, you rock! 😀

Comments are closed.