Wednesday, April 13, 2011

ASHX Generic Handler in ASP.Net

Problem:
I was working on WCF project where I was returning the list of objects, each object contained a field that holds Image, since it was a WCF project so I had to send images as byte[] array, now problem was that the picture was in byte[] array format, ASP.Net page does't convert it automatically into Image and when binding ListView to the collection, it was converting my byte[] array to a text field instead of Image.

Impact:
Web page does't display Images.

Solution:
Solution to that problem is to use ashx page. When creating a web page that dynamically returns an Image, XML file, PDF file or other non html web pages from the query string we use ashx page to perform those actions.

This solution will show how to use ahsx page to dynamically convert byte[] array to an image.

Step 1: Add new Generic Handler by right clicking on web project->Add New Item then select Generic Handler. Give it any name you want, I named mine HttpHandler.We need to pass the query string to the handler and handler will convert the byte[] array to an image and return a Url of that image, to do that go back to your aspx web page, in the ListView Item templet look for the column that is bound to the Image. It should look something like this.

ImageUrl='<%# Eval("Image") %>' //where Image is the name of the column.

Since ListView is bound to a collection of record and each record has an ID column that is associated with the Image, we will pass that Id as a query string instead of Image, and since we already have a collection we could create a session object that stores that collection so that we could access it in our handler, so do all that first replace your Eval("Image") with the following.

ImageUrl='<%# "HttpHandler.ashx?id=" + Eval("Id") %>'


Now we are passing the Id of that record to the HttpHandler.

Step 2: Create a Http Session object.
In the code behind file of you page, go to Page load method and create a session and pass your collection to that session.

private MovieServiceClient _movieService;
private List<Movie> _movies;

protected void Page_Load(object sender, EventArgs e)
{
        try
        {
            _movieService = new MovieServiceClient("MovieService_WsHttp");
            _movies = _movieService.GetAllMovies();
            Session["session"] = _movies;
        }
        catch (FaultException ex)
        {
            ErrorLabel.Text = ex.Message;
        }
        catch (Exception ex)
        {
            ErrorLabel.Text = ex.Message;
        }
}
        
Step 3: Code to convert byte[] into an image using HttpHandler.

In HttpHandler page we need to call session object and by default we sessions are not enabled in ashx pages, we use IRequiresSessionState Interface to enable it. Write the following code in your Process request method().


public class HttpHandler : IHttpHandler, IRequiresSessionState
{
    public void ProcessRequest (HttpContext context)
    {
        try
        {
            context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
            context.Response.BufferOutput = false;
            //get the id from the query string.
            int id = Int32.Parse(context.Request.QueryString["id"]);
            //set the type to Image/jpeg, or png or gif, any type that you are returning.
            context.Response.ContentType = "Image/jpeg";
            //get the session object.
            context.Session["session"] = HttpContext.Current.Session["session"];
            if (context.Session["session"] != null)
            {
                //pass the session object to a List<>
                var list = context.Session["session"];

                foreach (var movie in (List<Service.Movie>)list)
                {
                    //check if the id of that record matches to that record.
                    if (id == movie.Id)
                    {
                        //set the response that convert byte[] to an image.
                        context.Response.BinaryWrite(movie.Image);
                        break;
                    }
                }

            }
        }
        catch (Exception ex)
        {
            context.Response.Write(ex.Message);
        }
      
    }

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

this will return one image at a time as your ListView loop through all the records, your web page should now show that Image.

3 comments:

  1. You can Get Image from Generic HTTP Handler file by implementing HttpHandler interface.
    Here is live downloadable C# Examples and VB.Net Examples.
    http://jayeshsorathia.blogspot.com/2013/01/net-tips-get-image-from-generic-http-handler-file.html

    ReplyDelete
  2. Impressive web site, Distinguished feedback that can tackle. Im moving forward and may apply to my current job as a pet sitter, which is very enjoyable, but I need to additional expand. Regards.
    The Web Handlers

    ReplyDelete
  3. Here whatever the data given for ASHX Generic Handler in ASP.Net in C# Training is accurate and also C# Online Training Exception handling mechanism is also very useful.

    ReplyDelete