Image Retrieval using ASP.NET MVC 4.0 WebAPI with HttpResponseMessage

Posted by: Mahesh Sabnis , on 1/20/2013, in Category ASP.NET MVC
Views: 95103
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:

sql-server-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:

image-employee

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:

mvc-web-api

Conclusion

The above approach is very useful when images needs to be fetched form various location like FileServer, CloudBlob etc.

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Mahesh Sabnis is a DotNetCurry author and a Microsoft MVP having over two decades of experience in IT education and development. He is a Microsoft Certified Trainer (MCT) since 2005 and has conducted various Corporate Training programs for .NET Technologies (all versions), and Front-end technologies like Angular and React. Follow him on twitter @maheshdotnet or connect with him on LinkedIn


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by Darrel Miller on Sunday, January 20, 2013 10:17 AM
Why not pass the byte array from step 1 into the ByteArrayContent in step 6 and skip steps 2-5?
Comment posted by Suprotim Agarwal on Tuesday, January 22, 2013 3:55 AM
I like Darrel's suggestion. Sounds like the right way to do this.

@Mahesh Sabnis, any particular reason of not using the ByteArray coming from the Database directly into the ByteArrayContent? One reason I can think of is if you want to manipulate the image after retrieving - eg: adding watermark.
Comment posted by Jeremy S on Thursday, February 7, 2013 4:23 AM
The real question is why you have images in the db in the first place.

A *slightly* more practical example would get the image from disk, or an Amazon S3 bucket, since that's where everyone seems to store stuff nowadays.
Comment posted by newpostalcode on Thursday, February 28, 2013 6:12 AM
every country have different postal code or zip code therefore u can search postal code i our site.

http://www.newpostalcode.com/
Comment posted by Dmitry G on Monday, March 4, 2013 3:14 PM
Code style is really bad, deprecated image column type is used. Did not continue reading
Comment posted by Dmitry G on Monday, March 4, 2013 3:16 PM
Yuck, code does very silly things also. Huge dislike for this article
Comment posted by grreshma on Monday, April 8, 2013 11:54 PM
How to display an image after upload button click before saving to DB in asp.net mvc2
Comment posted by Name: on Thursday, May 30, 2013 11:36 PM
Comment
Comment posted by anil babu on Friday, June 21, 2013 4:17 AM
How to Store Images database and also perform all curd operations using ASP.NET MVC

I am performing normal data to store in database at the time use upload control to store the images to database how to do?

I am new to Mvc

Gove me one simple example on this complete code for that

please help me
Comment posted by kiran on Wednesday, July 3, 2013 2:04 AM
sss
Comment posted by kiran on Wednesday, July 3, 2013 2:06 AM
Hi I need to save a image using webapi
Comment posted by anil on Friday, July 12, 2013 6:18 AM
Get and display particular image along with data from database using ASP.NET MVC
4 hours, 59 minutes ago|LINK

Table:

public int ActorID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Price { get; set; }
[DataType(DataType.ImageUrl)]
public string Image { get; set; }

My Controller code:

public ActionResult Details(int id)
{
Actor ac = db.Actors.Single(x => x.ActorID == id);
return View(ac);

View:



@model MvcApplication1.Models.Actor

@{
ViewBag.Title = "Details";
}
<div style="font-family:Arial">
<h2>Details</h2>

<fieldset>
<legend>Actor</legend>

<div class="display-label">
@Html.DisplayNameFor(model => model.Name)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.Name)
</div>

<div class="display-label">
@Html.DisplayNameFor(model => model.Description)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.Description)
</div>

<div class="display-label">
@Html.DisplayNameFor(model => model.Price)
</div>
<div class="display-field">
@Html.DisplayFor(model => model.Price)
</div>

<div class="display-label">
@Html.DisplayNameFor(model => model.Image)
</div>
<div class="display-field">
@*@Html.DisplayFor(model => model.Image)*@
<img src="@Url.Content(@Model.Image)"/>

</div>
</fieldset>
</div>
<p>
@Html.ActionLink("Edit", "Edit", new { id=Model.ActorID }) |
@Html.ActionLink("Back to List", "Index")
</p>

This is my code At the time of clicking Details option It will display data correctly But ,Along with IMAGE not displaying,

please Correct my above code
Comment posted by anil on Tuesday, August 20, 2013 7:15 AM
This is my sample data from database,

ID Name ImageUrl

1   a       http://notous.blob.core.windows.net/images/1-9.jpg

2   b       http://notous.blob.core.windows.net/images/10_discount-150x150.jpg

3    c      http://notous.blob.core.windows.net/images/FB-button-341x341.png

I want display this data not for same This ImageURL display as image in My view Using ASP.NET MVC,

And also At the time of insert also after uploading the image save in database Like above(its possible???)

please help me,I am new to this MVC
Comment posted by Shiv Kumar on Thursday, October 10, 2013 11:22 PM
Sir,
please tell me how to save image using ajax post method in mvc
Comment posted by Jasraj on Tuesday, November 19, 2013 12:43 PM
I want to save Employee record with employee image.so how to post this one please help. i am using web api with mvc4.
Comment posted by Jayakumar on Sunday, August 17, 2014 6:58 AM
I need also this
I want to save Employee record with employee image.so how to post this one please help. i am using web api with mvc4.