HomeASP.NET Handling Dynamic Images in ASP.NET 3.5 AJA...
Handling Dynamic Images in ASP.NET 3.5 AJAX Applications
In the examples in the first part of this series, we discussed ways to make static image data persist in the server side files or databases. Nevertheless, in many other web applications, such as those on finance and economics sites, the images or charts are usually generated on the server side dynamically, and then sent back to the browser side in binary data via the HttpResponse output stream. This article, the conclusion to this two-part series, will show you how.
Contributed by Xianzhong Zhu Rating: / 9 September 03, 2008
How can you create and manipulate these kinds of dynamic server side images? Traditionally, most solutions fall back on third party libraries or other applications-provided image engines (such as Microsoft Office). Nowadays, things have changed drastically; GDI+, the next generation of image engine under .NET environments, offers a solution. ASP.NET applications can use GDI+ as the back-end image engine to generate any required static or dynamic images or charts on the fly.
As you may have realized from reading my previous articles, GDI+ brings forward a fully object-oriented programming model instead of the device context and object handle to greatly simplify the image handling in .NET environments. The most important concept introduced in GDI+ is Graphics, which plays the role of a central controller when rendering. The other important concepts are Image class, Bitmap class, and many other new object models.
Moreover, it is worth noticing that, to provide images dynamically, you must utilize a custom HTTP handler. The modes for the handler to obtain the image bits should rest on their inner implementation. There are generally three ways to do this: store the image bits in a database, ASP.NET Cache, or generate the image data dynamically.
In this section, we are going to show you another interesting ASP.NET AJAX based message board sample. This sample is more complex that the previous ones: it uses an .xml file to hold message data, and the myNorthWind.mdf database to store verification code related data. And also, it uses an ASP.NET AJAX Toolkit control, NoBot, to automatically judge whether the message data entered is the result of an action by a human being or done by a robot instead of traditional manual programming.
First, you can look at one of the running time snapshots of the message board application, as is shown in Figure 4.
Figure 4-using the ASP.NET AJAX Toolkit control-NoBot to help to block off possible rubbish message
As the ResponseMinimumDelaySeconds property of the NoBot control hints, if it takes less than 15 seconds to enter all the message related data, the NoBot control will give a 'Suspicious Robot action...' prompt at the bottom and record this piece of information.
Now, let us dissect the how-to behind the scene.
Introducing the ASP.NET AJAX Toolkit control NoBot
NoBot is one of the great ASP.NET AJAX Toolkit controls that attempts to provide CAPTCHA-like bot/spam prevention without requiring any user interaction. This approach is easier to bypass than an implementation that requires actual human intervention, but NoBot has the benefit of being completely invisible. NoBot is probably most relevant for low-traffic sites where blog/comment spam is a problem and 100% effectiveness is not required.
In all, NoBot employs the following different anti-bot techniques:
Forcing the client's browser to perform a configurable JavaScript calculation and verifying the result as part of the postback. (Ex: the calculation may be a simple numeric one, or may also involve the DOM for added assurance that a browser is involved).
Enforcing a configurable delay between when a form is requested and when it can be posted back. (Ex: a human is unlikely to complete a form in less than two seconds).
Enforcing a configurable limit to the number of acceptable requests per IP address per unit of time. (Ex: a human is unlikely to submit the same form more than five times in one minute).
Note you can test NoBot by violating any of the above techniques: posting back quickly, posting back many times, or disabling JavaScript in the browser.
In this sample, the GuestBook.xml file under the App_Data folder is used to store the message information submitted by users. Moreover, the other two classes, GuestBook and Comment, are auxiliary classes to maintain this kind of data. The following defines the schema of this .xml file and already entered data:
<comment name="Mike" text="Thank you. This helps me a lot!" />
<comment name="John" text="I like your ASP.NET AJAX article. Would you please provide the related source code?" />
</GuestBook>
Next, the SQL Server 2005 database myNorthWind.mdf with only a table namedcodetableis defined to persist the verifying codes to help generate the verifying picture. In this sample, we put a string, 'GenerateCAPTCHATest' to the field Code in the codetable table to be used to generate the verification code (five characters are selected at random here).
Next, let us delve into the most interesting point in this sample.
Using GDI+ to Create the Verifying Picture in the Custom HTTP Handler
In this sample, we mainly employ two techniques to hold up the possible robot action. One is to use the above-introduced ASP.NET AJAX Toolkit control, NoBot, which is designed to achieve the result from the angle of time. In other words, only the data entered within specified time is allowed. The other solution is to take the traditional action, which is to draw some characters commingled with some pictures so that only users entering the specified correct characters can continue to take the next step.
For convenience, let's again look at the pictures which contain the letters users are required to enter, as shown Figure 5 below.
Figure 5-only users that are able to enter the letters within the picture below is allowed to leave work
In this sample, to accomplish the above second blocking solution we have recourse to a custom HTTP handler, GenerateCAPTCHA.ashx. As you have guessed, all the secrets behind the scene are finished within the important function named ProcessRequest, defined in this HTTP handler. The following lists the complete source code of this function.
// render the verification code
public void ProcessRequest (HttpContext context)
{
// Create the Bitmap
using (Bitmap objBitmap = new Bitmap(_width, _height, PixelFormat.Format32bppArgb))
{
// create the canvas
using (Graphics objGraphics = Graphics.FromImage(objBitmap))
//you can use the following two sentence to create a unique GUID to access the newly-generated verifying code
//here we simply hard code it
//Guid guid = System.Guid.NewGuid();
// string strGuid = guid.ToString();
string strGuid = "CAPTCHA";
if (strGuid != String.Empty)
{
HttpRuntime.Cache.Insert(strGuid, _randomText);
}
}
}
I've put enough comments in the code that additional explanation should not be necessary. As for the other helper functions used in it, you can refer to the source code, which can be downloaded at the end of this article.
As for adding this sample required .aspx page, it is very easy. With Visual Studio 2008's built-in support for ASP.NET AJAX Extensions, you can directly add an AJAX web form, as is shown in Figure 6 below.
Figure 6-Adding an AJAX web form in Visual Studio 2008
As many web developers prefer to do, we have also leveraged <table> elements to lay out the page. Now, let's look at the HTML elements related definitions below:
First, you may notice that the ASP.NET AJAX server side controls ScriptManager and UpdatePanel are employed, which nearly all ASP.NET AJAX server-centric applications must put into use. Therefore, we do not dwell upon them.
Second, you should see that the important ASP.NET data source control ObjectDataSource appears herein. It is used to provide data for the FormView 'fvAddComment' and the DataList control 'dlComments.' This is typical ASP.NET 2.0 programming.
In the middle of the code hides the AJAX Toolkit control NoBot (with its ID being 'myNoBot'). There are two properties, ResponseMinimumDelaySeconds and OnGenerateChallengeAndResponse, which need to be discussed. The ResponseMinimumDelaySeconds property is set to 15 seconds, which means that within this period of time, if the "Submit" button is pressed, then the current action is suspected to be from a robot, as a result of which the submitting content is rejected and a warning message is thrown at the left bottom of the page.
In this function, a <div> element with random width and height is generated and then added onto the DOM tree in the page. At the same time, the sum of the width and height is stored, and a JavaScript code snippet is written in the page. Note that this JavaScript code snippet will be invoked at the client-side running time to find the above <div> and obtain its factual sum of its width and height. In this way, when the page postback takes place, the NoBot control can compare the expected value with that fetched from the browser to judge whether the client side is a browser and further judge whether or not the action came from a robot.
Summary
In this two-part series, we have extensively examined the image-related issues under the ASP.NET 3.5 environment by building several simple yet typical sample applications for the corresponding image solutions. One important point you should take notice of is that nearly all the solutions are in relation to the HTTP handlers. Therefore, it is strongly suggested that you become familiar with them first before diving into any of the image-related solutions provided here.
In the last section, we discussed how to use a custom HTTP handler in ASP.NET 3.5 environments to generate images and charts dynamically. Yet, it is noticeable that the HTTP handler is not the recommended tool for creating advanced diagrams. In fact, the HTTP handler is especially suitable to display images at the running time. To generate dynamic diagrams, the preferable solution is to seek help from the server side controls that are developed based upon the HTML <img> element.
Feel free to have a look at the source code for these two articles: