I am working in VS2010 RC at the time of this posting.
I am working with a set of images stored in an SQL database in my ASP.NET MVC project. I would like to load the images asynchronously (and preferably effortlessly) and as “in-line” as possible from my pages. I wanted to create a controller action that returned an image.
Ideally, something that works into my page as simply as this:
The HTML that would be rendered might be like this (or, I could write it out myself if I don’t want to use the Url helper above):
My images were being returned from a LINQ to SQL method (a stored procedure that returned an Image field) and, so, were typed as System.Data.Linq.Binary
A Complicated Mess
I Binged around for a bit but was having trouble finding info that was relevant or entirely up-to-speed with the latest MVC bits. I was frustrated because, without much explanation, people were reverting to complicated HTTP handlers, building System.Drawing.Bitmap objects and subclassing ActionResult (which felt a little weird).
I came up with the following solution (which I wrote in my controller) by gleaning through a ton of different implementations:
public EmptyResult GetImage(int id)
Byte imageBytes = _repository.GetImage(id).ToArray();
Response.OutputStream.Write(imageBytes, 0, imageBytes.Length);
Response.ContentType = "image/png";
return new EmptyResult();
This afforded me the simple notational luxuries as listed above, but it felt a little wrong to be pumping out data to the response stream when I’m describing my method as an EmptyResult.
Easier Without Getting Harder
I didn’t want to run into creating inherited types and the likes without a good reason. This was as complicated as I wanted to get and I wanted to know if I should go further.
I posted a question to StackOverflow to that tune and got back a lead on a couple other candidates to work with. A quick lookup on FileContentResult and I was off to the races:
If you like (and to facilitate testing) you can also easily implement a subclass of FileContentResult and pre-set the image type; then all you’d be doing is returning a new PngResult(byteshere).
To Be Fair…
I don’t mean to condemn any of the earlier efforts. In fact, some were pretty ingenious considering the state of MVC over a year ago.
The types that are available now in ASP.NET MVC make it very easy to return an image from a controller action, even if that image is a byte array or stored as a LINQ Binary type.