Click here to Skip to main content
Click here to Skip to main content

A spam safe link control

, 7 May 2004
Rate this:
Please Sign up or sign in to vote.
This control can show an e-mail address as a link on a web page without the risk of the address being captured by spammers.

Introduction

If you want to show an e-mail address on a web page, you usually insert some HTML code like this:

<a href="mailto:name@mydomain.com">Contact</a>

Unfortunately, this type of code can easily be captured by spammers, and soon your address will be distributed on CDs to bad people. Your inbox will be full of unsolicited mail.

There's a way to deal with this problem, involving JavaScript. When JavaScript is not supported by the client, you can still provide the visitor with an image that shows the address.

Because this situation is recurring on web pages all the time, I decided to create a user control that deals with it. It will show the mail address just as you would expect it, but it will be spam-safe.

From now on, you can just drop the SpamSafeLink control on your ASP.NET page, set one or two properties, and the control will take care of the rest.

Installing the control

Just unzip the source files and copy both files SpamSafeLink.ascx and image.aspx to any folder in your website.

Using the control

In your editor (Web Matrix, C# Builder, Visual Studio, ...), drag the file SpamSafeLink.ascx onto your page, where you want the link to appear.

If you use another editor, you can add the control manually. Add this directive on top of the page:

<%@ Register TagPrefix="rw" TagName="SpamSafeLink" Src="SpamSafeLink.ascx" %>

Then, add a tag like this in your HTML code where you want the e-mail link to be displayed:

<rw:SpamSafeLink id="SpamSafeLink1" Address="test@test.com" Text="Contact" 
    BgColor="White" LinkColor="Blue" Size="12" FontName="Verdana" runat="server">
</rw:SpamSafeLink>

Next, make sure you use the appropriate settings.

demo.aspx

Use the demo page demo.aspx as a sample showing you how the SpamSafeLink control could be used. For testing purposes, you may want to disable JavaScript temporarily in your browser. Look here for instructions about how to enable/disable JavaScript. For fast comparison, you can have your browser prompt you every time.

These are the control properties that you can set:

  1. Address (String)

    This is the most important property. Enter the e-mail address that you want to use as the link target. When the client doesn't support JavaScript, it is used as the caption, but it will not work as a link.

  2. Text (String)

    This is the caption that will be displayed as a link. Only set this property when you want a caption that is NOT the mail address. When omitted, the Address property will be used instead. When the client doesn't support JavaScript, this property is ignored.

  3. BgColor (Color)

    This is the background color for the image (white, by default). When the client supports JavaScript, this property is ignored.

  4. LinkColor (Color)

    This is the text color for the image (blue, by default). When the client supports JavaScript, this property is ignored.

  5. Size (Integer)

    This is the text size for the image (8, by default). When the client supports JavaScript, this property is ignored.

  6. FontName (String)

    The name of the font face for the image ("Verdana", by default). When the client supports JavaScript, this property is ignored.

When the client doesn't support JavaScript, the control will just show the address, but it will not work as a link.

How it works

SpamSafeLink.ascx

The control simply splits the address in 2 parts, using the ampersand as the separator. During rendering, the control just outputs both parts separately with a small JavaScript. In that way, a spam bot scouting for addresses in your page will be confused. It's still a link, but the real address is not easily readable in the page's HTML.

<script language="Javascript" type="text/javascript">
<!--
  document.write("<a href='mail")
  document.write("to:")
  document.write("<%=_Address1%>")
  document.write("@")
  document.write("<%=_Address2%>")
  document.write("'>")
  document.write("<%=Text%>")
  document.write("</a>")
//-->
</script>

When JavaScript is not supported on the client, the browser will execute the <noscript> block.

<noscript>
    <img src="<%=GetImageURL()%>" />
</noscript>

The function GetImageURL() calls an ASP.NET file that will create the image on-the-fly:

    Private Function GetImageURL() As String
      Return "image.aspx?address1=" & _address1 & "&address2=" & _address2 & _
          "&linkcolor=" & _LinkColor.ToArgb() & "&bgcolor=" & _BgColor.ToArgb() & _
          "&size=" & _Size & "&FontName=" & _FontName
    End Function

The address, caption, colors, size and font are taken from the user control's properties, and passed as GET query parameters. This block calls the code in image.aspx, which will create a GIF image that just displays the e-mail address. It will not work as a clickable link in this case.

In order to save processor time, the cache duration time is set very high.

image.aspx

<%@ Page Language="VB" %>
<%@ OutputCache Duration="3600" 
  VaryByParam="Address1;Address2;size;bgcolor;linkcolor;FontName" %>
<%@ import Namespace="System.Drawing" %>
<%@ import Namespace="System.Drawing.Imaging" %>
<%@ import Namespace="System.Drawing.Drawing2D" %>
<script runat="server">

    Sub Page_Init( sender As Object, e As EventArgs)

        ' Since we are outputting a Gif, set the ContentType appropriately
        Response.ContentType = "image/gif"

        Dim FontName As String = Request.QueryString("FontName")
        Dim Address As String = Request.QueryString("Address1") _
                & "@" & Request.QueryString("Address2")
        Dim objFont As Font = New Font(FontName, CInt(Request.QueryString("size")))

        ' Create a Temporary Bitmap instance
        ' and a Graphics instance to get the image size
        Dim objBitmapTemp As Bitmap= New Bitmap(1, 1)
        Dim objGraphicsTemp As Graphics = Graphics.FromImage(objBitmapTemp)

        Dim ImageSize As SizeF = objGraphicsTemp.MeasureString(Address,objFont)
        ' clean up...
        objGraphicsTemp.Dispose()
        objBitmapTemp.Dispose()

        ' Create a Bitmap instance and a Graphics instance
        Dim objBitmap As Bitmap= New Bitmap(Convert.ToInt32(ImageSize.width),_
                                           Convert.ToInt32(ImageSize.height))
        Dim objGraphics As Graphics = Graphics.FromImage(objBitmap)

        Dim BgBrush = New SolidBrush(Color.FromArgb(Request.QueryString("bgcolor")))
        Dim TextBrush = New _
             SolidBrush(Color.FromArgb(Request.QueryString("linkcolor")))

        objGraphics.FillRectangle(BgBrush, 0, 0, _
           ImageSize.width, ImageSize.height)  ' Background
        objGraphics.DrawString(Address, objFont,_
                            TextBrush, 0, 0) ' Draw address

        ' Save the image to a file
        objBitmap.Save(Response.OutputStream, ImageFormat.Gif)

        ' clean up...
        objGraphics.Dispose()
        objBitmap.Dispose()

    End Sub

</script>
<!-- no HTML content -->

Future

Here are some ideas for future improvement:

  • Extract the font face, color and size from a style sheet (if the page uses one).
  • Use relative sizes instead of absolute ones.
  • Convert it to a full custom control.

If anyone decides to extend this, or has any comments or questions, then it would be great to hear from you.

Points of interest

  • user controls.
  • using GDI+ graphics in ASP.NET.

History

5/8/2004: Release of version 1.0.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Jos Branders
Web Developer
Belgium Belgium
No Biography provided

Comments and Discussions

 
GeneralImage Alternate PinmemberMagadass20-Mar-05 16:16 
GeneralRe: Image Alternate PinmemberFelipe Amorim23-Sep-05 9:49 
GeneralThis should be an ASHX PinsussMark Weiss3-Sep-04 4:43 
GeneralRe: This should be an ASHX PinmemberJos Branders4-Sep-04 23:37 
GeneralRe: This should be an ASHX PinmemberMagadass20-Mar-05 16:26 
GeneralGood idea PinstaffNishant S8-May-04 7:34 

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

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

| Advertise | Privacy | Mobile
Web04 | 2.8.140721.1 | Last Updated 8 May 2004
Article Copyright 2004 by Jos Branders
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid