Howto: create a custom httpHandler

If you would like to (for example) make sure all the jpegs on your site are displayed including a copyright text or something like that, you could use the example I posted before. But it would be easier to write a custom httpHandler. Here’s a small howto:

1. Add a class to a WebApplication, and give it a decent name. Mine is customHandler.
2. Have the class implement the IHttpHandler interface (found in the System.Web namespace)
3. Implement the right methods
4. Use ‘ProcessRequest‘ to process the request the way you want to
5. Register the handler in the web.config
6. ‘Register’ the handler in IIS
7. You’re good to go!

Now for some exampe-code. Steps 1 to 4 can be found here:

public
class customHandler : IHttpHandler
{
    public customHandler()
    {
    }

    public void ProcessRequest(HttpContext context)
    {
        Image image;
        string plaatje;
        Graphics graphics;

        plaatje = context.Request.PhysicalPath;
        image = Image.FromFile(plaatje);
        graphics = Graphics.FromImage(image);

        //TODO: add dynamic calculation of the drawstring location
        graphics.DrawString("bloggingabout.net",
new Font("Verdana", 14, FontStyle.Bold), new SolidBrush(Color.White), 10, 280);
        graphics.Dispose();

        context.Response.ContentType = "image/jpeg";
        image.Save(context.Response.OutputStream, ImageFormat.Jpeg);
        context.Response.End();
   
}

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

Step 5 looks a little bit like this:

<httpHandlers>
    <add verb="*" path="*.jpg" type="handlerTest.customHandler, handlerTest"/>
</httpHandlers>

Step 6 is a little bit tricky. You will have to open the Internet Information Services manager and open the properties for the the website you want the handler to work for. Om the first tab page, open up configuration. Now, first select a file extension which is served by ASP.Net, like .asax or .aspx and click edit. Copy the file that’s used over there (it should be C:WINDOWSMicrosoft.NETFrameworkv1.1.4322aspnet_isapi.dll). Close the dialog and click to add a new one. Here, put the copied value in the right textbox and fill in .jpg as the extension you want to be handled. Next close all open boxes by clicking OK and you should be ready to go.

The image it produced with my code:

By |October 27th, 2005|.Net, HowTo|1 Comment

HowTo: implement a list that sorts based on value ( not key ! )

Sometimes you need a sorted list. You would think in that case the SortedList class would help out, but unfortunately this one only sorts based on the key, while most of the time you would like to sort based on the value. 

Now I can almost hear you think: "Why not switch key and value then?" Well, let’s say the key you would like to use is the username for a software program or a website. The value is the full name of the user. It is possible two different users have the same full name (John Smith), but have different usernames (j.smith and johns). In that case, switching keys and values won’t help you, because keys need to be unique in a SortedList.

To implement your own ‘sorted list’ which sorts based on the value, first create a class (or a struct) to hold the data for the key and the value you would like to retain in the list. Make sure you implement the IComparable interface, because you will need this to be able to sort the class/struct. For this example I implemented both key and value as a string:

public struct KeyValuePair : IComparable
{

    private string theKey;
    private string theValue;
           
    public string Key
    {
        get
        {
            return theKey;
        }
    }
 
    public string Value
    {
        get
        {
            return theValue;
        }
    }
 
    public KeyValuePair(string key, string value)
    {
        theKey = key;
        theValue = value;
    }
 
    public int CompareTo(object obj)
    {
        if (obj == null)
        {
            return 1;
        }
        else
        {
            KeyValuePair check = (KeyValuePair)obj;
            return Value.CompareTo(check.Value);
        }
    }
}
 
Now when you want a value-sorted list, you can simply create an ArrayList, add KeyValuePairs to the ArrayList, call the Sort() method (which calls the CompareTo() method for each of the objects that exist in the ArrayList) and see that the items in your ArrayList are sorted based on the values of all KeyValuePairs!!!

Sample:

    ArrayList arrayList;
    arrayList = new ArrayList();
    arrayList.Add(new KeyValuePair("1", "bbb"));
    arrayList.Add(new KeyValuePair("2", "ccc"));
    arrayList.Add(new KeyValuePair("3", "aaa"));
    arrayList.Sort();
    foreach (KeyValuePair keyValuePair in arrayList)
    {
        proofTextBox.Text += keyValuePair.Key + " : " + keyValuePair.Value + Environment.NewLine;
    }

By |October 4th, 2005|.Net, HowTo|1 Comment

HowTo: Thread safe singleton implementation of a class

Normally, if you would like a singleton implementation of a class, you would go about it a little bit like this:

public class BloggingAbout
{
   
private static BloggingAbout bloggingAbout;
   
    private BloggingAbout()
    {
    }

    public static BloggingAbout BloggingAboutInstance
    {
        get
       
{
            if (bloggingAbout == null)
            {
                bloggingAbout = new BloggingAbout();
            }
            return bloggingAbout;
        }
    }
}

The trouble here is that this implementation is not thread safe. The reason I post this is I recently ran into some code of an old colleague of mine (from my former employee) and some tests showed his singleton class was instantiated several times when the application was stressed with requests from the start, which caused unwanted lag in the application. Apparently him not implementing the Singleton pattern thread safe caused this, so I fixed it.
It’s not thread safe because two different threads could both evaluate if (bloggingAbout == nulland find it to be true and create an instance, which violates the singleton pattern. To make sure this doesn’t happen, you could use locking which would result in this code:

public class BloggingAbout
{
   
private static BloggingAbout bloggingAbout;
    private static object lockObject = new object();
    
    private BloggingAbout()
    {
    }

    public static BloggingAbout BloggingAboutInstance
    {
        get
       
{
            lock(lockObject)
            {

                if (bloggingAbout == null)
                {
                    bloggingAbout = new BloggingAbout();
                }
                return bloggingAbout;
            }
        }
    }
}

The lock statement ensures that one thread does not enter a critical section of code while another thread is in that critical section. If another thread attempts to enter a locked section of code, it will wait (block) until the object is released. This is the reason the lockObject has to exist even before calling the static property BloggingAboutInstance.

By |September 21st, 2005|.Net, HowTo|1 Comment

Howto: present a Crystal Reports report as a PDF in an ASP.Net web application (without using temporary files)

This one is actually quite simple: Crystal Reports supports exporting to a PDF. Exporting can be done to disk, or to a stream. And a stream can be written to the Repsonse property of a page. And there you go ;)


// Variable declaration
   CrystalTest crystalTest;
   MemoryStream memoryStream;

// Create a new instance of the report you want to display as a PDF
   crystalTest = new
CrystalTest();
// TODO: Add some stuff here to fill the report with data

// Export the report to a stream with the PDF format
   memoryStream = (MemoryStream)crystalTest.ExportToStream(ExportFormatType.PortableDocFormat);
// Set the ContentType to pdf, add a header for the length
// and write the contents of the memorystream to the response
   Response.ContentType = “application/pdf”;
   Response.AddHeader(“content-length”, Convert.ToString(memoryStream.Length));
   Response.BinaryWrite(memoryStream.ToArray());
//End the response
   Response.End();

HOWTO: display your assembly @ Add Reference

You might want to be able to let your assembly show up in the Add Reference window in Visual Studio without the user having to browse for it. When you install your assembly in the GAC, it doesn’t automatically show up in the Add Reference window, because it doesn’t enumerate all assemblies in the GAC. Installing in the GAC only eliminates the need to copy assemblies localy when referencing them. Microsoft doesn’t recommend putting assemblies in the GAC by the way…

You can add your assembly to the Add Reference window by editing the registry. First, make a new key (name not important, I’ll use ‘GumpsBlog’) in the following subkey:
HKCU – SOFTWARE – Microsoft – .NETFramework – AssemblyFolders

Then, in the key you created, let the default value point to the location where your assemblies can be found. This should look something like this (sorry for the Dutch interface, click to enlarge):

Next, restart Visual Studio and see your assemblies in the Add Reference window!

By the way, placing this registry key under the HKLM makes the assemblies in the specified folder available to any user, not just the current one…

By |June 17th, 2005|.Net, HowTo|1 Comment

HOWTO: Encode a password using MD5 in C# (or: howto calculate the MD5 hash for a string)

The following method returns the MD5 hash for any given string. For instance for a password. It might be of some assistance when you’re trying to validate user credentials but you don’t want to store the password readable in the database.

For this method, you’ll need the following using statements:

using System;
using
System.Text;
using
System.Security.Cryptography;



public
string EncodePassword(string originalPassword)
{
  //Declarations
  Byte[] originalBytes;
  Byte[] encodedBytes;
  MD5 md5;

  //Instantiate MD5CryptoServiceProvider, get bytes for original password and compute hash (encoded password)
  md5 = new
MD5CryptoServiceProvider();
  originalBytes = ASCIIEncoding.Default.GetBytes(originalPassword);
  encodedBytes = md5.ComputeHash(originalBytes);

  //Convert encoded bytes back to a ‘readable’ string
  return
BitConverter.ToString(encodedBytes);
}

Hmmm… I seem to write comments when I’m trying to explain something ;)

HOWTO: Draw your own string (URL, copyright) on each displayed picture in an ASP.Net website

The AdRotator .Net provides can be used to show a different image each time a page is visited. You could write a webpage which does this for you, but it’s probably not very useful. Although you need to change the XML file when changing the images to be showed when you use an AdRotator, but that’s not the issue here.
Something .Net doesn’t deliver is a control to add your own text to an image when it is displayed on a webpage. And that’s exactly what we will be doing in this HowTo.

Below is the code I placed inside the page load of a webpage called showimg.aspx. To display images with the text I want to print on them, you don’t use <IMG src=”test.jpg”/>, but instead you use <IMG src=”showimg.aspx?image=test.jpg”/>.


Please note: this code is illustrative. Normally you would perform a number of checks. For instance check if the querystring is filled, if the image exists, if the text will fit the image, and so on…


  //Const declarations
  const string outtext = “bloggingabout.net/rick”;
  //Variable declarations
  string img;
  Image image;
  Graphics graphics;
  Font font;
  SizeF textSize;
  SolidBrush brush;


  //Set font & brush and get image from QueryString
  img = Request.QueryString[“image”];
  font = new Font(“Verdana”, 9);
  brush = new SolidBrush(Color.Black);


  //Opening the specified image from the images folder
  image = Image.FromFile(Server.MapPath(“images/” + img));
  //Create graphics object for painting
  graphics = Graphics.FromImage(image);
  //Get the size the text will be with the defined font
  textSize = graphics.MeasureString(outtext, font);
  //Set SmoothingMode to AntiAlias
  graphics.SmoothingMode = SmoothingMode.AntiAlias;
  //Draw the string in the lower right corner of the image
  graphics.DrawString(outtext, font, brush, 
                      image.Width – textSize.Width,
                      image.Height – textSize.Height);
  //Dispose used objects
  graphics.Dispose();
  font.Dispose();
  brush.Dispose();

//Writing the image to the browser as the response:
  //Set contenttype to image
  Response.ContentType = “image/jpeg”;
  //Save the changed image to response
  image.Save(Response.OutputStream, ImageFormat.Jpeg);
  //End repsone: it’s done ;)
  Response.End();
  //Dispose the image object
  image.Dispose();

HOWTO: create an animated GIF using .Net (C#)

.Net (at least 1.1, they might incorporate it in 2.0) does not give you possibilities to create animated GIFs through GDI+. But there are ways to make them! This solution is one I used myself, and I’m very pleased!

//Variable declaration
StringCollection stringCollection;
MemoryStream memoryStream;
BinaryWriter binaryWriter;
Image image;
Byte[] buf1;
Byte[] buf2;
Byte[] buf3;
//Variable declaration

stringCollection = a_StringCollection_containing_images;

Response.ContentType = “Image/gif”;
memoryStream = new MemoryStream();
buf2 = new Byte[19];
buf3 = new Byte[8];
buf2[0] = 33;  //extension introducer
buf2[1] = 255; //application extension
buf2[2] = 11;  //size of block
buf2[3] = 78;  //N
buf2[4] = 69;  //E
buf2[5] = 84;  //T
buf2[6] = 83;  //S
buf2[7] = 67;  //C
buf2[8] = 65;  //A
buf2[9] = 80;  //P
buf2[10] = 69; //E
buf2[11] = 50; //2
buf2[12] = 46; //.
buf2[13] = 48; //0
buf2[14] = 3;  //Size of block
buf2[15] = 1;  //
buf2[16] = 0;  //
buf2[17] = 0;  //
buf2[18] = 0;  //Block terminator
buf3[0] = 33;  //Extension introducer
buf3[1] = 249; //Graphic control extension
buf3[2] = 4;   //Size of block
buf3[3] = 9;   //Flags: reserved, disposal method, user input, transparent color
buf3[4] = 10;  //Delay time low byte
buf3[5] = 3;   //Delay time high byte
buf3[6] = 255; //Transparent color index
buf3[7] = 0;   //Block terminator
binaryWriter = new BinaryWriter(Response.OutputStream);
for (int picCount = 0; picCount < stringCollection.Count; picCount++)
{
  
image = Bitmap.FromFile(stringCollection[picCount]);
  
image.Save(memoryStream, ImageFormat.Gif);
  
buf1 = memoryStream.ToArray();

  
if (picCount == 0)
  
{
      //only write these the first time….
     
binaryWriter.Write(buf1, 0, 781); //Header & global color table
      binaryWriter.Write(buf2, 0, 19); //Application extension
  
}

   binaryWriter.Write(buf3, 0, 8); //Graphic extension
   binaryWriter.Write(buf1, 789, buf1.Length – 790); //Image data

   if (picCount == stringCollection.Count – 1)
   {
      //only write this one the last time….
     
binaryWriter.Write(“;”); //Image terminator
   }

   memoryStream.SetLength(0);
}
binaryWriter.Close();
Response.End();






Edit
To illustratie te poor quality I’m talking about, I’ve added an animated gif created dynamically using the code above, based on a directory containing some source images. Look at the ‘raster’ in the darker images… (the source images were solid filled 200 x 200 GIF’s, created using Paint.Net, where they look fine)









Edit2
Damn Paint.Net! I make a test-image: looks great. I save it as a GIF: still looks great. Use it in my anigif-code: no more greatness. I reopen the file in Paint.Net: then it’s fubar! Creating the testfiles in oldskool Paint solves this (because you only have GIF-supported colors in your toolbar)…

When you are converting a file to a GIF, old Paint warns you because you might be losing color information, Paint.Net does not. Paint reloads the file the way you saved it so you see what remains. Paint.Net does not. These are two wannahaves on Paint.Net for me!





Edit3
Thanks to Dennis for pointing out a small glitch in my type-work.
It should have been ‘picCount == stringCollection.Count – 1’.