Advantage of HttpHandler - A Certificate example


Scenario

You are a developer at Grade Nineteen University. One of the recent requirments the management had is to create an online certificate.
So that the students that pass out should be able to view their Certificates online. This will definitely add some technological edge to the university.

Requirement

The student will be given his own certification url as following: http://www.cert19.edu/certificates/100.cert

On accessing the url, the following Certifcate image will be displayed for the student id: 100

(100.cert should be interpreted in server as "Show Certificate for Student Id as 100")

Grade19.png


Easy Way of Implementation - But not the Best

The first thought of implementation would be to create jpg files for all the students and copy them into the cert folder of the website. This approach is feasible but the following overheads would exist:

  • For 1000 students that pass each year, 50 MB disk space would be required.
  • While backing up database of site, we have to do backup of jpg files too, which is tedious.
If we have to take a backup of the site, we have to copy the files separately and do the database backup separately.


Http Handlers for the Rescue - A better Approach

We can achieve the same behavior with little overheads – by avoiding files creation for certificates.

We can use the database records to dynamically create certificate based on the student url.

By default the ISAPI handlers, handle the .aspx url extensions. We have to create a new handler for .jpg file handling that would be redirected to our certificate creation code.


Steps

1. Create a new web application project

Create a new web application project and name it as Grade19University.


2. Create a new class and implement the IHttpHandler interface

Create a new class named "CertHandler" and implement the IHttpHandler interface

Add the following code.

public class CertHandler : IHttpHandler
{
        public bool IsReusable
        {
            get { return false; }
        }

        /// <summary>
        /// Core Method
        /// </summary>
        /// <param name="context"></param>
        public void ProcessRequest(HttpContext context)
        {
            StudentLibrary studentLibrary = new StudentLibrary();

            Bitmap image = studentLibrary.GetCertificate(context.Request.Url.ToString());

            if (image != null)
            {
                context.Response.ContentType = "image/bmp";
                image.Save(context.Response.OutputStream, ImageFormat.Bmp);
            }
            else
                context.Response.Write("Invalid Student Id!");
        }
}

// The StudentLibrary class contains all student id lookup and image generating code
// A Certificate template is stored in application resource file



3. Modify the config file

Open the web.config file and in the httpHandlers section add the new verb

<httpHandlers>
      <
add verb="*" path="*.cert" validate="false" type="Grade19University.CertHandler, Grade19University"/>
</httpHandlers>


4. Run the application and test the url

You can execute the application and see the certificates. The library contains 3 students information, which can be viewed as:

http://localhost/certificates/100.cert
http://localhost/certificates/101.cert
http://localhost/certificates/102.cert


5. The StudentLibrary Class


public
class StudentLibrary
{

private static IList<Student> _students = new List<Student>();
/// <summary>
/// Create a list of students
/// </summary>
static StudentLibrary()
{

_students.Add(
new Student() { Id = 100, Name = "Mike Robert", Qualification="BS in Computer Science", Grade="First Class" });
_students.Add(
new Student() { Id = 101, Name = "Jim Rone", Qualification = "BE in Mechanical", Grade = "First Class with Distinction" });
_students.Add(
new Student() { Id = 102, Name = "Albert Dane", Qualification = "BS in Electronics", Grade = "First Class" });

}
private Student GetStudent(string url)
{

int id = GetStudentIdFromUrl(url);
var student = (from s in _students
where s.Id == id
select s).FirstOrDefault();






return student;

}
private int GetStudentIdFromUrl(string url)
{

string substr = GetStringBetween(url, "/certificates/", ".cert");
int id = 0;
if (int.TryParse(substr, out id))
return id;
return id;

}
private string GetStringBetween(string Data, string StartKey, string EndKey)
{

if (String.IsNullOrEmpty(Data) || String.IsNullOrEmpty(StartKey) || String.IsNullOrEmpty(EndKey))
return String.Empty;
if (!Data.Contains(StartKey) || !Data.Contains(EndKey))
return String.Empty;
int ix_start = Data.IndexOf(StartKey);
int ix_end = Data.IndexOf(EndKey, ix_start + StartKey.Length);
int ValueStart = ix_start + StartKey.Length;
string ret = Data.Substring(ValueStart, ix_end - ix_start - StartKey.Length);
return ret;

}
public Bitmap GetCertificate(string url)
{

Student student = GetStudent(url);
if (student != null)
{

Bitmap bitmap = new Bitmap(Images.Cert);
Graphics graphics = Graphics.FromImage(bitmap);
graphics.DrawString(student.Name,
new Font("Calibri", 14, FontStyle.Bold), Brushes.Black, new PointF(173, 102));
graphics.DrawString(student.Qualification,
new Font("Calibri", 14, FontStyle.Bold), Brushes.Black, new PointF(130, 130));
graphics.DrawString(student.Grade,
new Font("Calibri", 14, FontStyle.Bold), Brushes.Black, new PointF(85, 160));
return bitmap;

}

return null;

}


}



public class Student
{
   public int Id { get; set; }
   public string Name { get; set; }
   public string Qualification { get; set; }
   public string Grade { get; set; }
}

Note


We can add more optimizations to the code like verifying the raw url, customizing the error messages etc.