Creating A Captha In Silverlight 2
Something I came across while creating a personal website some time ago in ASP.Net was creating Captcha images to validate
a user. When Silverlight 2 came out I was looking to update that site to Silverlight as a learning project. One of the first
tasks was to recreate the sign up and login process. I found a few ways to do this but here is the solution I liked the most.
This solution will use a WCF service to communicate with the Silverlight application.
The first thing we need to do is create a place to store the captha text in our web application. To do this open the code
for your .aspx page that contains your silverlight application and add the follwing code.
public string CaptchaString
{
get { return Session["CaptchaString"].ToString(); }
set { Session["CaptchaString"] = value.ToString(); }
}
In order to use Session variables we also need to make sure that this entry is in our web.config file.
< system.serviceModel>
< serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
< /system.serviceModel>
Once we have defined our variable to store the captha text we need to create a WCF service to set the text,
create the image of the text and perform the validation on the users input. To do this add a new WCF service to
your web application and add the following to the service contract.
[OperationContract]
byte[] GetCapthcaImage();
[OperationContract]
void SetCapthcaText(string captchaText);
[OperationContract]
bool ValidateCapthcaInput(string captchaInput);
First we will look at the SetCapthaText method. This one is fairly straight forward. It takes a string as
input and sets our Session variable.
public void SetCapthcaText(string captchaText)
{
HttpContext.Current.Session["CaptchaString"] = captchaText;
}
The ValidateCapthaInput is also very simple. It takes the users input, tests it against our Session variable
and returns a boolean.
public bool ValidateCapthcaInput(string captchaInput)
{
if (captchaInput.Equals(HttpContext.Current.Session["CaptchaString"].ToString()))
{
return true;
}
else
{
return false;
}
}
Finally we have our GetCaptchaImage method. This is where the image is created and then passed back to our
Silverlight application so that we can show it to the user. This code can be changed to give more or less
distorted images.
public byte[] GetCapthcaImage()
{
Bitmap objBMP = new System.Drawing.Bitmap(80, 20);
Graphics objGraphics = System.Drawing.Graphics.FromImage(objBMP);
objGraphics.Clear(Color.Green);
objGraphics.TextRenderingHint = TextRenderingHint.AntiAlias;
Font objFont = new Font("Arial", 8, FontStyle.Bold);
string randomStr = HttpContext.Current.Session["CaptchaString"].ToString();
int[] myIntArray = new int[5];
objGraphics.DrawString(randomStr, objFont, Brushes.White, 3, 3);
MemoryStream ms = new MemoryStream();
objBMP.Save(ms, ImageFormat.Jpeg);
objFont.Dispose();
objGraphics.Dispose();
objBMP.Dispose();
return ms.GetBuffer();
}
We need to send the image as a byte array because we can not send an image through our service. In our Silverlight
application we will create our image from this byte array.
Now that we have built our service we need to add a reference to it in our Silverlight application. Right click on your
Silverlight application and select Add Service Reference. Select the service you created for the captcha control.
Below is a code snippet of my Page.xaml file. This will be whatever page you want to use the control on. I have added a
reference to my service called client that we will use to call the methods exposed from the service we created
earlier.
private CaptchaServiceReference.CaptchaClient client = new CaptchaClient();
When the page is initialized we call the SetCapthcaTextAsync and pass the string we want to have show up. It is best
to randomize this. For this example I have set it to "hello world". We also wire up our event handler for SetCapthcaTextCompleted.
public Page()
{
InitializeComponent();
client.SetCapthcaTextCompleted += new EventHandler(client_SetCapthcaTextCompleted);
client.SetCapthcaTextAsync("hello world");
}
When the capthca text is set we then ask for captcha image by calling GetCapthcaImageAsync(). This will use the value that we just
set in our Session variable to create our image.
void client_SetCapthcaTextCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
client.GetCapthcaImageCompleted += new EventHandler(client_GetCapthcaImageCompleted);
client.GetCapthcaImageAsync();
}
Once we have our byte array that is generated by the GetCapthcaImage method we need to create the image to display to the
user. We do this by creating a MemoryStream from the byte array. We then create a new Bitmap image and set the source
of the image to the MemoryStream we just created. This Bitmap image is then shown to the user using a simple Silverlight
image control.
void client_GetCapthcaImageCompleted(object sender, GetCapthcaImageCompletedEventArgs e)
{
MemoryStream stream = new MemoryStream(e.Result);
BitmapImage image = new BitmapImage();
image.SetSource(stream);
imgCaptcha.Source = image;
}
The last thing we need to do is validate the users input. In this example there is a textbox named tbxInput where the user
can input the text. When the submit button is pressed we initiate the following code to call the ValidateCapthcaInput() method.
private void Button_Click(object sender, RoutedEventArgs e)
{
client.ValidateCapthcaInputCompleted += new EventHandler(client_ValidateCapthcaInputCompleted);
client.ValidateCapthcaInputAsync(tbxInput.Text);
}
We can now take the result of the validation and decide what to do from there.
void client_ValidateCapthcaInputCompleted(object sender, ValidateCapthcaInputCompletedEventArgs e)
{
if (e.Result == true)
{
//Code if the input is correct
}
else
{
//Code if the input is not correct
}
}
This is really all there is to creating a Captcha in Silverlight 2.
Click here to download source code
Consultant Warehouse ©2009
|