Streaming Databased Images Using HttpHandler

For a long time now I have noticed something annoying when working on Web Application projects involving databased images on my local machine. By local I mean that it’s a typical environment with VS 2008 and SQL Server 2005 on my workstation. Whenever I use an HttpHandler to display the images on my local, only some of the images render on each page load.

However, when I push the application to a hosted environment, the problem usually disappears. However, I just pushed a new project out to a hosted environment and experienced the same problem as on my local – this time the site and the DB were on the same server in the hosting environment. Has anyone got a take on what’s happening here?

Here’s the handler:

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class FeaturedHandler : IHttpHandler
{
    Business biz = new Business();

    public void ProcessRequest(HttpContext context)
    {
        if (context.Request.QueryString["ListingID"] != null)
        {
            int listingID = Convert.ToInt32(context.Request.QueryString["ListingID"]);

            DataSet ds = biz.GetFeaturedImageByID(listingID);
            DataRow row = ds.Tables[0].Rows[0];
            byte[] featureImage = (byte[])row["Photo"];
            context.Response.ContentType = "image/jpeg";
            context.Response.OutputStream.Write(featureImage, 0, featureImage.Length);
        }
        else
            throw new ArgumentException("No ListingID parameter specified");
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

I have tried using a DB on a separate server but encountered the same problem. Should I be using a DataReader instead?

UPDATE
I should have used a DataReader initially since I am reading binary data.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

I finally got all images to render by changing the value of the IsReusable property to true:

    public bool IsReusable
    {
        get
        {
            return true;
        }
    }

Apparently, this keeps the handler in memory and able to handle multiple requests. When set to false, it had to create a new instance of the handler for each incoming request.

Method 2

By this:

Whenever I use an HttpHandler to
display the images on my local, only a
portion of the images render on each
page load.

Do you mean that the same image appear on places where different images should appear or that some images appear and some doesn’t show at all?

In your case the difference by switching isReusable to true is that new Business(); will be called once for multiple images. If isReusable is false the new Business(); will be called once per image. This means that if you have several images per page new Business(); will be called several times for this particular page.

Also I strongly suggest changing this:

if (context.Request.QueryString["ListingID"] != null)
{
    int listingID = Convert.ToInt32(context.Request.QueryString["ListingID"]);

with:

string listingIdParam = context.Request.QueryString["ListingID"];
if (listingIdParam != null)
{
    int listingID = Convert.ToInt32(listingIdParam);

This will save you null reference exceptions that usually surface only under heavy load. Also the above will prevent serving the wrong image to a request especially when isReusable is true.

I cannot determine what the problem was exactly but I can definitely say that setting the isReusable flag was just a workaround and doesn’t fix your problem. Also when a problem like this is reproducible only in certain environment that means that either it’s a thread problem or there is some difference in request handling (different web server – IIS6, IIS7, development server).

Maybe posting the Business class and it’s constructor can shed some light.
Also I suggest implementing some kind of error logging to trap exceptions in the handler and review them.

Method 3

If you are serving images directly, do not forget to set the correct caching headers, i.e. etags and expires. If you don’t you are really going to hit your database hard and use up your bandwidth.

You will need to handle the following http headers:

  • ETag
  • Expires
  • Last-Modified
  • If-Match
  • If-None-Match
  • If-Modified-Since
  • If-Unmodified-Since
  • Unless-Modified-Since

For an example http handler that does this check out:
http://code.google.com/p/talifun-web/wiki/StaticFileHandler


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x