Click here to Skip to main content
15,881,804 members
Articles / Web Development / ASP.NET

ImageLabel Control for ASP.NET (Potential CAPTCHA Control)

Rate me:
Please Sign up or sign in to vote.
4.31/5 (2 votes)
13 Jan 2007CPOL2 min read 42.5K   110   27   7
Labels are generated as images instead of text to have more privacy without any configurations and without HttpHandlers.

Sample Image - ImageLabel.png

Introduction

This an ASP.NET web control for generating labels as images. You might want to do that for providing security for e-mail crawlers or to disallow copy paste of the text. Many similar controls have been implemented as HttpHandlers, so you need more configuration to make them work. However, this control does not need any configuration. You just need to use it just like any other ASP.NET control like Label. Almost all of the label formatting options are included, like font size, backcolor, and forecolor.

How does it work

The code can be separated to two parts: the variable initializations, and the render part. The OnInit event is used for the preparation of a URL string of the image to be generated. The URL string is stored in a private member of the class with the client to make sure that controls draw themselves. There is a trick here. This control is executed twice by the browser. To make things work, the query string is in a predefined format. The browser tries to display the image specified by a tag, and the init code tries to read whether it is coming from a querystring or not to generate the image.

C#
protected override void OnInit(EventArgs e)
{    
    if (this.Context.Request.QueryString[QueryStringText()] != null)
    {
        DrawImage(this.Text);
    }  
    this.m_URL = Context.Request.Url.AbsolutePath + "?" + 
                    secretQueryString+ this.ClientID + "=1";
   base.OnInit(e);
}

However, there is another problem. Since the browser is executing twice, the control state is also different, so storing the display text value will not work using the ViewState. As a result, I store it in the session variable, that is cleared after rendering the image. The Text property of the control handles the session and the automatic code generated by the designer. You know, when you set the text of the control from the designer, after compilation, it is executed by the ASP.NET process. I'm telling this because this control runs two controls with different life cycles. "this.Context.Request.QueryString[QueryStringText()]" makes sure that we are coming from the main page, rather than the forked control.

C#
public string Text
{
    get
    {
        if (DesignMode)
        {
            if (ViewState["Text"] == null)
                ViewState["Text"] = string.Empty;
            return (string)ViewState["Text"];
        }
        else
        {
            string s = PossiblequeryString();

            if (!string.IsNullOrEmpty(s))
                return (string)Context.Session[s]; 
           

            
            if (Context.Session[SessionText()] == null)
                Context.Session[SessionText()] = string.Empty;
            return (string)Context.Session[SessionText()];
        }
    }

    set
    {
        if (DesignMode)
        {
            ViewState["Text"] = value;
        }
        else
        {

            if (PossiblequeryString() == null)
            {
                Context.Session[SessionText()] = value;
            }
       
        }
    }
}

The DrawImage function draws the image in memory and saves to the Response object. Since the Response.End method is executed, Render events will not be fired any more at image generation.

C#
strOutput.DrawString(Message, msgFont, new SolidBrush(foreColor), 1, 1);
MemoryStream memStream = new MemoryStream();
bmp.Save(memStream, System.Drawing.Imaging.ImageFormat.Png);

Context.Response.Clear();
Context.Response.ContentType = "image/png";
Context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
memStream.WriteTo(Context.Response.OutputStream);
Context.Session.Remove(SessionText());
Context.Response.OutputStream.Flush();
Context.Response.OutputStream.Close();
Context.Response.End();

The Render code is used for the rendering of the image. It is simply an image HTML tag pointing to the URL generated previously on onInit. To make the Visual Studio Designer happy and stop it complaining about exceptions, I also added code to render itself as a normal text control in the designer.

C#
protected override void Render(HtmlTextWriter writer)
{
    if (DesignMode)
    {
        base.Render(writer);
    }
    else
    {
        writer.AddAttribute(HtmlTextWriterAttribute.Src, this.m_URL);
        writer.RenderBeginTag(HtmlTextWriterTag.Img);
        writer.RenderEndTag();
    }
}

Conclusion

This control works without any configuration, and is easy to use as any other ASP.NET Web Control. It can be used to hide information from crawlers or robots. Although this is not implemented as a CAPTCHA control, that functionality can easily be added to the image generation.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Turkey Turkey

Comments and Discussions

 
GeneralRuntime Settings Pin
Brad Bruce29-Dec-06 9:46
Brad Bruce29-Dec-06 9:46 
AnswerRe: Runtime Settings Pin
Can Erten29-Dec-06 13:30
Can Erten29-Dec-06 13:30 
GeneralRe: Runtime Settings Pin
Brad Bruce29-Dec-06 14:08
Brad Bruce29-Dec-06 14:08 
AnswerRe: Runtime Settings Pin
Can Erten29-Dec-06 14:28
Can Erten29-Dec-06 14:28 
GeneralRe: Runtime Settings Pin
Brad Bruce30-Dec-06 7:30
Brad Bruce30-Dec-06 7:30 
AnswerRe: Runtime Settings Pin
Can Erten13-Jan-07 13:46
Can Erten13-Jan-07 13:46 
GeneralDown with HttpHandlers Pin
Brad Bruce29-Dec-06 5:22
Brad Bruce29-Dec-06 5:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.