Hi,

i have followed a tutorial and modified it to get a image stored as a blob from MSSQL, it is working perfectly - however i utilised handlers in this tutorial. and while it is working fine - id quite like to understand what is going on!

<%@ WebHandler Language="C#" Class="Handler" %>

 

using System;
using System.Web;
using System.Data.SqlClient;
using System.Data;
using System.IO;
using System.Collections.Specialized;
 

public class Handler : IHttpHandler {

 

    public string GetConnectionString()

    { // i think i know this bit gets connection string from web.config!
       return System.Configuration.ConfigurationManager.ConnectionStrings["ConString"].ConnectionString;
    }

    public void ProcessRequest(HttpContext context)

    {   //what does this context.request mean?
        string id = context.Request.QueryString["CarID"]; 
        if (id != null)

        {

            try
            {
                //creates new memory stream for the binary image data i guess!
                MemoryStream memoryStream = new MemoryStream();
                //create new sql connection and sql command
                SqlConnection connection = new SqlConnection(GetConnectionString());
                string sql = "SELECT * FROM Car WHERE CarID = @CarID";
                //creates new sql command
                SqlCommand cmd = new SqlCommand(sql, connection);
                //add paramaters to command
                cmd.Parameters.AddWithValue("@CarID", id);

                //open connection
                connection.Open();
                //what does this do and why is it needed?
                SqlDataReader reader = cmd.ExecuteReader();
                //im guessing this has something to do with the datareader
                reader.Read();



                //byte array for storing the image i guess
                byte[] file = (byte[])reader["Image"];


                //close the reader and connection
                reader.Close();
                connection.Close();
                
                //does this write to the array?
                memoryStream.Write(file, 0, file.Length);
                //i have no idea what these 2 do
                context.Response.Buffer = true;
                context.Response.BinaryWrite(file);
                //dispose of memory stream? :p lol
                memoryStream.Dispose();

            }
            catch
            {
            }

        }

    }

    //set to false - what is it? - i think its false because of something to do with threading  

    public bool IsReusable {

        get {

            return false;

        }

    }

}

if anyone could also tell me the order of whats going on that would be most appriciated :) like i say ive got it working fine - but what good is following tutorials if i dont understand it!

thanks guys xx :)

>what this code is doing please? :)

Based upon ID (request parameter) value, code reads a row from the Car table. After that, exception will be thrown when data reader has no row, otherwise it writes an array of bytes (image content) into the response buffer.

1) what does this context.request mean?
string id = context.Request.QueryString["CarID"];
Ans.
Here, context is type of HttpContext. HttpContext is class which is used to get important information about each individual http request. the object of httpcotext provide access to Request, Response and Server object directly for request.
So here, the code only retrieves CarID from coming http request questystring. I mean http://localhost/testweb/webform1.aspx?CarID=1. so the code store "1" in string id variable.

2) what does this do and why is it needed?
SqlDataReader reader = cmd.ExecuteReader();
Ans.
here ExecuteReader() method returns the object of SqlDataReader which holds the number of rows from your executed query. So here it's only return Image from your table for particular CarID.

3)does this write to the array?
memoryStream.Write(file, 0, file.Length);
Ans.
It reads data from buffer(file) and write a block of byte to the current stream(memoryStream).

4)i have no idea what these 2 do
context.Response.Buffer = true;
context.Response.BinaryWrite(file);
Ans.
Buffer determines whether output to client browser is buffered or not by setting true/false. Here it saying output to client browser is buffered.
BinaryWrite(), writes string of binary character to http output stream by reading from buffer.

Hope this will help you !

Hi Loveforfire,

I'd like to comment on a few parts of the code.

Firstly this line:

context.Response.Buffer = true;

Setting the Buffer property to true tells the web response to wait until the complete response has finished processing before sending data to the client. If this was false it'd be possible to send data to the client before the response has finished processing.

This line:

context.Response.BinaryWrite(file);

This writes the file bytes to the response stream. This is the important part of the code as this line outputs the file to the client.

and finally, here are my comments on the memory stream code:

//creates new memory stream for the binary image data i guess!
//Yes, that's correct
MemoryStream memoryStream = new MemoryStream();
//does this write to the array?
//No, this writes the contents of the array to the memory stream
memoryStream.Write(file, 0, file.Length);
//dispose of memory stream? :p lol
//Yes, that's correct
memoryStream.Dispose();

The code writes the content of file to the memory stream, but the doesn't do anything with the memory stream apart from dispose it! There is no need to use the memory stream as we write the file bytes directly to the response.

In short we've created a memory stream, written data to it, and then done nothing with it. I'm not suprised that this part of the code confused you, as it definitely doesn't behave as the author intended.

I hope this has been helpful :-)

DoctaJonez


By the way, this is how I'd rewrite the code (removing the memory stream):

<%@ WebHandler Language="C#" Class="Handler" %>

 

using System;
using System.Web;
using System.Data.SqlClient;
using System.Data;
using System.IO;
using System.Collections.Specialized;
 

public class Handler : IHttpHandler {

 

    public string GetConnectionString()

    { // i think i know this bit gets connection string from web.config!
       return System.Configuration.ConfigurationManager.ConnectionStrings["ConString"].ConnectionString;
    }

    public void ProcessRequest(HttpContext context)

    {   //what does this context.request mean?
        string id = context.Request.QueryString["CarID"]; 
        if (id != null)

        {

            try
            {
                //create new sql connection and sql command
                SqlConnection connection = new SqlConnection(GetConnectionString());
                string sql = "SELECT * FROM Car WHERE CarID = @CarID";
                //creates new sql command
                SqlCommand cmd = new SqlCommand(sql, connection);
                //add paramaters to command
                cmd.Parameters.AddWithValue("@CarID", id);

                //open connection
                connection.Open();
                //what does this do and why is it needed?
                SqlDataReader reader = cmd.ExecuteReader();
                //im guessing this has something to do with the datareader
                reader.Read();

                //byte array for storing the image i guess
                byte[] file = (byte[])reader["Image"];

                //close the reader and connection
                reader.Close();
                connection.Close();

                //i have no idea what these 2 do
                context.Response.Buffer = true;
                context.Response.BinaryWrite(file);
            }
            catch
            {
            }

        }

    }

    //set to false - what is it? - i think its false because of something to do with threading  

    public bool IsReusable {

        get {

            return false;

        }

    }

}

amazing responces thank you :)

i have one more question however, a subsequent tutorial has shown me how to replace broken image links (when no image is read) with a default image stored on the file system.

can anyone explain the following bit of code to me (mainly why and what file.openread is used for, and why fs.read is needed if file.openread is there?)

catch 
                {                
                    
                    FileStream fs = File.OpenRead(HttpContext.Current.Server.MapPath("~/NoImage.png"));
                                        
                    file = new byte[fs.Length];
                    
                    
                    fs.Read(file, 0, file.Length);
                
                }

thanks (and rep to both of you for helpful replies :)

File.OpenRead is basically 2 components in 1, File represents a call to System.IO.File() where OpenRead is the method used within System.IO.File to determine the file handling process, in this case, allow opening and reading of the file but not writing.

fs.Read is basically calling your fileStream that you created and telling it to use the Read method with the use of the file variable determined above it.

Hope this helps :) Please remember to mark solved if your issue is resolved.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.