Image Retrieval using ASP.NET MVC 4.0 WebAPI with HttpResponseMessage
Posted by: Mahesh Sabnis ,
on 1/20/2013,
in
Category ASP.NET MVC
Abstract: This article demonstrates how to use ASP.NET WebAPI to retrieve images from a database server
Recently during a discussion on WebAPI capabilities, I was asked about the HttpResponseMessage message class and its messaging features, particularly on sending an Image as a response. We all know that an action method exposed via WebAPI can be consumed directly in jQuery using AJAX. Since a JSON response is returned by default in a WebAPI, the question that arises is how to send the image in the response object.
I worked on this scenario and this article is the outcome of it. For simplicity, we assume images are stored in the SQL Server database in the form of Binary objects, (they can just be images on a file server, or blob container on cloud etc) too.
The overall idea is that the binary data from the database server is converted into the images and then this needs to be passed using HttpResponseMessage object.
To implement the scenario, the following objects are used:
- Bitmap - The objects encapsulate a GDI+ bitmap. This consist of pixel data for graphics image.
- FileStream and MemoryStream - Objects used to manage file on the server and pass to the caller using HttpResponseMessage content.
- Image - Class provides functionality for managing Images.
- ByteArrayContent - Class representing the Http content based byte array sent as a response.
The most important part here is how to specify the HttpResponseMessage header format for images. This is achieved by the MediaTypeHeaderValue class.
For this implementation, I have used a SQL Server database with the following table:

The table contains Employee images using ‘image’ Data Type of the SQL server database. (Note: When you test the source code in the article, you should have a table on your database server with images in it.)
Step 1: Open VS 2012 and create a new ASP.NET MVC 4.0 project. Name it as ‘MVC40_WebAPI_ImageReader’. In this project, add a new ADO.NET EF mapping of the above table in the Models folder. After completing the wizard, the table mapping will be as shown below:
Build the project.
Step 2: In the Controller folder, right click and add a new API controller, name it as ‘EmployeeController’. Import the following namespaces in the class:
using MVC40_WebAPI_ImageReader.Models;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web.Hosting;
using System.Web.Http;
Step 3: Define an instance of the ADO.NET EF and add the GetImage() method in the class. This method accepts the Id for EmpNo and queries the Employees records. Once the Employee record is found, the binary data for the Employee Image is extracted and the Bitmap is created. This bitmap is then saved on the server using Stream and then Image object is read from the stream. This Image is then saved into the MemoryStream which is then sent as a ByteContentArray as a content of the HttpResponseMessage object. The class implementation is as shown below (the steps are also outlined in the comments):
namespace MVC40_WebAPI_ImageReader.Controllers
{
public class EmployeeController : ApiController
{
//ADO.NET EF object
CompanyEntities objContext;
public EmployeeController()
{
objContext = new CompanyEntities();
}
/// <summary>
/// Method for
/// 1. Read the ByteArray from Sql Server Database
/// 2. Convert the Byte Array into Bitmap.
/// 3. Save the file on the server using FileStream object.
/// 4. Get the Image object from FileStream
/// 5. Save the Image object into MemoryStream
/// 6. The MemoryStream is passed into the HttpResponse in Http Content based byte Array using ByteArrayContent object
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
public HttpResponseMessage GetImage(int Id)
{
HttpResponseMessage response = new HttpResponseMessage();
//1
var Emp = (from e in objContext.ImageEmployees
where e.EmpNo == Id
select e).First();
//2
TypeConverter typeConverter = TypeDescriptor.GetConverter(typeof(Bitmap));
Bitmap bmp = (Bitmap)typeConverter.ConvertFrom(Emp.EmpImage);
//3
var Fs = new FileStream(HostingEnvironment.MapPath("~/Images") + @"\I" + Id.ToString() + ".png", FileMode.Create);
bmp.Save(Fs,ImageFormat.Png);
bmp.Dispose();
//4
Image img = Image.FromStream(Fs);
Fs.Close();
Fs.Dispose();
//5
MemoryStream ms = new MemoryStream();
img.Save(ms, ImageFormat.Png);
//6
response.Content = new ByteArrayContent(ms.ToArray());
ms.Close();
ms.Dispose();
response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
response.StatusCode = HttpStatusCode.OK;
return response;
}
}
}
Step 4: In the controller, add a new empty controller and name it as ‘ImageEmployeeController’. You will have an Index method. Generate a new Index view and add the following HTML markup in it:
<table>
<tr>
<td>Enter EmpNo </td>
<td>
<input type="text" id="txteno" />
</td>
<td>
<input type="button" id="btngetemp" value="Get Employee" />
</td>
</tr>
<tr>
<td>
<img id="emimage" src="" height="100" width="100"/>
</td>
</tr>
</table>
Add the following script in the view:
<script type="text/javascript">
$(document).ready(function () {
$("#btngetemp").click(function () {
var EmpNo = $("#txteno").val();
$("#emimage").attr("src", "http://localhost:4208/api/Employee/" + EmpNo);
});
});
</script>
The above script specifies that the ‘src’ attribute is added with the URL of the WebAPI. This executes the API method and sends the response as image format as ‘image/png’ and displays the image in the img tag.
Step 5: Run the application and enter EmpNo in the TextBox. After clicking on the button, the result will be as shown below:
Conclusion
The above approach is very useful when images needs to be fetched form various location like FileServer, CloudBlob etc.
Give me a +1 if you think it was a good article. Thanks!