|
well this is final, this control is not working in a real web enviroment,
but nice try, and nice captcha image, nice ideas, nice example,
I get this code, and some other code form codeproject with image captcha and made a new one that work.
thanks.
|
|
|
|
|
My web application use form authentication
I place the CAPTCHA Server Control in the login page, it can't display the image.
But if I place the CAPTCHA Server Control in other page, it display well.
Is it not suitable for form authentication? or How can I do?
|
|
|
|
|
I have the same problem!
|
|
|
|
|
me too - no answer as yet.
Jeff? can you help?
cheers
|
|
|
|
|
Hey there,
I just encountered this issue and the solution for me was pretty simple. My site has all pages protected by default and then I make exceptions for the landing page and registration page. (the reg page is the page that uses the captcha). Because the control uses the httphandler captchaimage.aspx like an actual page to render the image, you need to make sure this is accessable to anonymous users. so try adding the following to your web.config file just after the section.
<location path="CaptchaImage.aspx">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
Hope that does the trick for you!
Phill
|
|
|
|
|
Great
void izmoto(char* szKwazi);
|
|
|
|
|
Yep, didn't manage to get the control working within a page with Form Authentication before the User has been authenticated. I'd guess the problem is the ImageHandler. Found some other Controls based on the one described here (E.g. http://www.mondor.org/captcha.aspx[^]), all of them have the same problem.
|
|
|
|
|
My Login Page was in subdirectory...Image was not shown, because this directory was protected, so a call from CaptchaImage.aspx would not be working.
Thats the reason on other pages or after login it works.
I changed the Class of CaptchaControl.vb
[...]
.Write("[...]
so i added the call of upper directory. and now it works on the login page, but not on usual page (outside subdir). But its ok for me.
Thanks for Captcha Tool
|
|
|
|
|
First, sorry for some change to CHS... but it work...
CaptchaControl.cs
<code>
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
namespace WebControlCaptcha_for_C_sharp
{
public class CaptchaControl :
System.Web.UI.WebControls.WebControl, INamingContainer, IPostBackDataHandler, IValidator
{
public enum Layout
{
Horizontal,
Vertical,
};
public enum CacheType
{
HttpRuntime,
Session,
};
private int _timeoutSecondsMax = 90;
private int _timeoutSecondsMin = 3;
private bool _userValidated = true;
private String _text = "Enter the code shown:";
private String _font = "";
private CaptchaImage _captcha = new CaptchaImage();
private Layout _layoutStyle = Layout.Horizontal;
private String _prevguid;
private String _errorMessage = "";
private CacheType _cacheStrategy = CacheType.HttpRuntime;
#region ///Public Properties
[Bindable(true),
Category("Appearance"),
DefaultValue("The text you typed does not match the text in the image."),
Description("Message to display in a Validation Summary when the CAPTCHA fails to validate.")]
public String ErrorMessage
{
get
{
if( ! _userValidated )
return _errorMessage;
else
return "";
}
set
{
_errorMessage = value;
}
}
[Browsable(false),
Category("Behavior"),
DefaultValue(true),
Description("Is Valid"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsValid
{
get
{
return _userValidated;
}
set { }
}
//
//
//
public override bool Enabled
{
get
{
return base.Enabled;
}
set
{
base.Enabled = value;
// When a validator is disabled, generally, the intent is not to
// make the page invalid for that round trip.
if( ! value )
_userValidated = true;
}
}
[DefaultValue("Enter the code shown above:"),
Description("Instructional text displayed next to CAPTCHA image."),
Category("Appearance")]
public String Text
{
get
{
return _text;
}
set
{
_text = value;
}
}
[DefaultValue( CaptchaControl.Layout.Horizontal ),
Description("Determines if image and input area are displayed horizontally, or vertically."),
Category("Captcha")]
public Layout LayoutStyle
{
get
{
return _layoutStyle;
}
set
{
_layoutStyle = value;
}
}
[DefaultValue( CaptchaControl.CacheType.HttpRuntime ),
Description("Determines if CAPTCHA codes are stored in HttpRuntime (fast, but local to current server) or Session (more portable across web farms)."),
Category("Captcha")]
public CacheType CacheStrategy
{
get
{
return _cacheStrategy;
}
set
{
_cacheStrategy = value;
}
}
[Description("Returns True if the user was CAPTCHA validated after a postback."),
Category("Captcha")]
public bool UserValidated
{
get
{
return _userValidated;
}
}
[DefaultValue(""),
Description("Font used to render CAPTCHA text. If font name is blank, a random font will be chosen."),
Category("Captcha")]
public String CaptchaFont
{
get
{
return _font;
}
set
{
_font = value;
_captcha.Font = _font;
}
}
[DefaultValue(""),
Description("Characters used to render CAPTCHA text. A character will be picked randomly from the string."),
Category("Captcha")]
public String CaptchaChars
{
get
{
return _captcha.TextChars;
}
set
{
_captcha.TextChars = value;
}
}
[DefaultValue(5),
Description("Number of CaptchaChars used in the CAPTCHA text"),
Category("Captcha")]
public int CaptchaLength
{
get
{
return _captcha.TextLength;
}
set
{
_captcha.TextLength = value;
}
}
[DefaultValue(2),
Description("Minimum number of seconds CAPTCHA must be displayed before it is valid. If you're too fast, you must be a robot. Set to zero to disable."),
Category("Captcha")]
public int CaptchaMinTimeout
{
get
{
return _timeoutSecondsMin;
}
set
{
if (value > 15)
throw new ArgumentOutOfRangeException("CaptchaTimeout", "Timeout must be less than 15 seconds. Humans aren't that slow!");
_timeoutSecondsMin = value;
}
}
[DefaultValue(90),
Description("Maximum number of seconds CAPTCHA will be cached and valid. If you're too slow, you may be a CAPTCHA hack attempt. Set to zero to disable."),
Category("Captcha")]
public int CaptchaMaxTimeout
{
get
{
return _timeoutSecondsMax;
}
set
{
if( value < 15 && value != 0 )
throw new ArgumentOutOfRangeException("CaptchaTimeout", "Timeout must be greater than 15 seconds. Humans can't type that fast!");
_timeoutSecondsMax = value;
}
}
[DefaultValue(50),
Description("Height of generated CAPTCHA image."),
Category("Captcha")]
public int CaptchaHeight
{
get
{
return _captcha.Height;
}
set
{
_captcha.Height = value;
}
}
[DefaultValue(180),
Description("Width of generated CAPTCHA image."),
Category("Captcha")]
public int CaptchaWidth
{
get
{
return _captcha.Width;
}
set
{
_captcha.Width = value;
}
}
[DefaultValue(CaptchaImage.FontWarpFactor.Low),
Description("Amount of random font warping used on the CAPTCHA text"),
Category("Captcha")]
public CaptchaImage.FontWarpFactor CaptchaFontWarping
{
get
{
return _captcha.FontWarp;
}
set
{
_captcha.FontWarp = value;
}
}
[DefaultValue( CaptchaImage.BackgroundNoiseLevel.Low ),
Description("Amount of background noise to generate in the CAPTCHA image"),
Category("Captcha")]
public CaptchaImage.BackgroundNoiseLevel CaptchaBackgroundNoise
{
get
{
return _captcha.BackgroundNoise;
}
set
{
_captcha.BackgroundNoise = value;
}
}
[DefaultValue( CaptchaImage.LineNoiseLevel.None ),
Description("Add line noise to the CAPTCHA image"),
Category("Captcha")]
public CaptchaImage.LineNoiseLevel CaptchaLineNoise
{
get
{
return _captcha.LineNoise;
}
set
{
_captcha.LineNoise = value;
}
}
#endregion
public void Validate()
{
//-- a no-op, since we validate in LoadPostData
}
private CaptchaImage GetCachedCaptcha( String guid )
{
if( _cacheStrategy == CacheType.HttpRuntime )
return (CaptchaImage)HttpRuntime.Cache.Get(guid) ;
else
return (CaptchaImage)HttpContext.Current.Session[guid];
}
private void RemoveCachedCaptcha( String guid )
{
if (_cacheStrategy == CacheType.HttpRuntime)
HttpRuntime.Cache.Remove(guid);
else
HttpContext.Current.Session.Remove(guid);
}
/// <summary>
/// are we in design mode?
/// </summary>
private bool IsDesignMode
{
get
{
return HttpContext.Current == null;
}
}
/// <summary>
/// Validate the user's text against the CAPTCHA text
/// </summary>
private void ValidateCaptcha( String userEntry )
{
if( !Visible || !Enabled )
{
_userValidated = true;
return;
}
//-- retrieve the previous captcha from the cache to inspect its properties
CaptchaImage ci = GetCachedCaptcha(_prevguid);
if( ci == null )
{
//this.ErrorMessage = "The code you typed has expired after " + this.CaptchaMaxTimeout + " seconds.";
this.ErrorMessage = "??????????" + this.CaptchaMaxTimeout + "?????";
_userValidated = false;
return;
}
//-- was it entered too quickly?
if( this.CaptchaMinTimeout > 0 )
{
if( ci.RenderedAt.AddSeconds( this.CaptchaMinTimeout ) > DateTime.Now )
{
_userValidated = false;
//this.ErrorMessage = "Code was typed too quickly. Wait at least " + this.CaptchaMinTimeout + " seconds.";
this.ErrorMessage = "?????????????" + this.CaptchaMinTimeout + "??????";
RemoveCachedCaptcha(_prevguid);
return;
}
}
if( String.Compare(userEntry, ci.Text, true) != 0 )
{
//this.ErrorMessage = "The code you typed does not match the code in the image.";
this.ErrorMessage = "????????????????";
_userValidated = false;
RemoveCachedCaptcha(_prevguid);
return;
}
_userValidated = true;
RemoveCachedCaptcha(_prevguid);
}
/// <summary>
/// returns HTML-ized color strings
/// </summary>
private String HtmlColor( Color color )
{
if( color.IsEmpty ) return "";
if( color.IsNamedColor )
return color.ToKnownColor().ToString();
if( color.IsSystemColor )
return color.ToString();
return "#" + color.ToArgb().ToString("x").Substring(2);
}
/// <summary>
/// returns css "style=" tag for this control
/// based on standard control visual properties
/// </summary>
private String CssStyle()
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
String strColor;
sb.Append(" style='");
if( BorderWidth.ToString().Length > 0 )
{
sb.Append("border-width:");
sb.Append(BorderWidth.ToString());
sb.Append(";");
}
if( BorderStyle != System.Web.UI.WebControls.BorderStyle.NotSet )
{
sb.Append("border-style:");
sb.Append(BorderStyle.ToString());
sb.Append(";");
}
strColor = HtmlColor(BorderColor);
if( strColor.Length > 0 )
{
sb.Append("border-color:");
sb.Append(strColor);
sb.Append(";");
}
strColor = HtmlColor(BackColor);
if( strColor.Length > 0 )
sb.Append("background-color:" + strColor + ";");
strColor = HtmlColor(ForeColor);
if( strColor.Length > 0 )
sb.Append("color:" + strColor + ";");
if( Font.Bold )
sb.Append("font-weight:bold;");
if( Font.Italic )
sb.Append("font-style:italic;");
if( Font.Underline )
sb.Append("text-decoration:underline;");
if( Font.Strikeout )
sb.Append("text-decoration:line-through;");
if( Font.Overline )
sb.Append("text-decoration:overline;");
if( Font.Size.ToString().Length > 0 )
sb.Append("font-size:" + Font.Size.ToString() + ";");
if( Font.Names.Length > 0 )
{
String strFontFamily;
sb.Append("font-family:");
int i=0;
for (strFontFamily = Font.Names[i]; i < Font.Names.Length; i++)
{
sb.Append(strFontFamily);
sb.Append(",");
}
sb.Length = sb.Length - 1;
sb.Append(";");
}
if( Height.ToString() != "" )
sb.Append("height:" + Height.ToString() + ";");
if( Width.ToString() != "" )
sb.Append("width:" + Width.ToString() + ";");
sb.Append("'");
if( sb.ToString() == " style=''" )
return "";
else
return sb.ToString();
}
/// <summary>
/// render raw control HTML to the page
/// </summary>
protected override void Render( HtmlTextWriter Output )
{
Output.Write("
if( CssClass != "" )
Output.Write(" class='" + CssClass + "'");
Output.Write( CssStyle() );
Output.Write(">");
//-- image DIV/SPAN
if( this.LayoutStyle == Layout.Vertical )
Output.Write("<div style="text-align:center;margin:5px;">");
else
Output.Write("<span style="margin:5px;float:left;">");
//-- this is the URL that triggers the CaptchaImageHandler
Output.Write("<img src="\"CaptchaImage.aspx");<br" mode="hold" /> if( ! IsDesignMode )
Output.Write("?guid=" + Convert.ToString(_captcha.UniqueId));
Output.Write("\" border='0'");
if( ToolTip.Length > 0 )
Output.Write(" alt='" + ToolTip + "'");
Output.Write(" width=" + _captcha.Width);
Output.Write(" height=" + _captcha.Height);
Output.Write(">");
if( this.LayoutStyle == Layout.Vertical )
Output.Write("</span></div>");
else
Output.Write("");
//-- text input and submit button DIV/SPAN
if( this.LayoutStyle == Layout.Vertical )
Output.Write("<div style="text-align:center;margin:5px;">");
else
Output.Write("<span style="margin:5px;float:left;">");
if( _text.Length > 0 )
{
Output.Write(_text);
Output.Write("<br>");
}
Output.Write("<input name=" + UniqueID + " type="text" size=");<br mode=" hold=" /"> Output.Write(_captcha.TextLength.ToString() );
Output.Write(" maxlength=");
Output.Write(_captcha.TextLength.ToString() );
if( AccessKey.Length > 0 )
Output.Write(" accesskey=" + AccessKey);
if( ! Enabled )
Output.Write(" disabled=\"disabled\"");
if( TabIndex > 0 )
Output.Write(" tabindex=" + TabIndex.ToString());
Output.Write(" value=''>");
if( this.LayoutStyle == Layout.Vertical )
Output.Write("</input></br></span></div>");
else
{
Output.Write("");
Output.Write("<br clear="all">");
}
//-- closing tag for master DIV
Output.Write("");
}
/// <summary>
/// generate a new captcha and store it in the ASP.NET Cache by unique GUID
/// </summary>
private void GenerateNewCaptcha()
{
if( ! IsDesignMode )
{
if( _cacheStrategy == CacheType.HttpRuntime )
{
HttpRuntime.Cache.Add( _captcha.UniqueId, _captcha, null,
DateTime.Now.AddSeconds( Convert.ToDouble( (this.CaptchaMaxTimeout == 0 ? 90 : this.CaptchaMaxTimeout) ) ),
TimeSpan.Zero, System.Web.Caching.CacheItemPriority.NotRemovable, null );
}
else
HttpContext.Current.Session.Add(_captcha.UniqueId, _captcha);
}
}
/// <summary>
/// Retrieve the user's CAPTCHA input from the posted data
/// </summary>
public bool LoadPostData( String PostDataKey, NameValueCollection Values )
{
ValidateCaptcha(Convert.ToString(Values[this.UniqueID]));
return false;
}
// just void
public void RaisePostDataChangedEvent()
{
}
protected override Object SaveControlState()
{
return (Object)_captcha.UniqueId;
}
protected override void LoadControlState( Object state )
{
if( state != null )
_prevguid = (String)state;
}
protected override void OnInit( System.EventArgs e )
{
base.OnInit(e);
Page.RegisterRequiresControlState(this);
Page.Validators.Add(this);
}
protected override void OnUnload( System.EventArgs e )
{
if (Page != null)
Page.Validators.Remove(this);
base.OnUnload(e);
}
protected override void OnPreRender( System.EventArgs e )
{
if( this.Visible )
GenerateNewCaptcha();
base.OnPreRender(e);
}
}
}
</br></code>
CaptchaImage.cs
<code>
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
namespace WebControlCaptcha_for_C_sharp
{
public class CaptchaImage
{
private int _height;
private int _width;
private Random _rand;
private DateTime _generatedAt;
private String _randomText;
private int _randomTextLength;
private String _randomTextChars;
private String _fontFamilyName;
private FontWarpFactor _fontWarp;
private BackgroundNoiseLevel _backgroundNoise;
private LineNoiseLevel _lineNoise;
private String _guid;
private String _fontWhitelist;
#region Public??
/// <summary>
/// Amount of random font warping to apply to rendered text
/// </summary>
public enum FontWarpFactor
{
None,
Low,
Medium,
High,
Extreme,
}
/// <summary>
/// Amount of background noise to add to rendered image
/// </summary>
public enum BackgroundNoiseLevel
{
None,
Low,
Medium,
High,
Extreme,
}
/// <summary>
/// Amount of curved line noise to add to rendered image
/// </summary>
public enum LineNoiseLevel
{
None,
Low,
Medium,
High,
Extreme,
}
#endregion
#region Public Properties
/// <summary>
/// Returns a GUID that uniquely identifies this Captcha
/// </summary>
public String UniqueId
{
get
{
return _guid;
}
}
/// <summary>
/// Returns the date and time this image was last rendered
/// </summary>
public DateTime RenderedAt
{
get
{
return _generatedAt;
}
}
/// <summary>
/// Font family to use when drawing the Captcha text. If no font is provided, a random font will be chosen from the font whitelist for each character.
/// </summary>
public String Font
{
get
{
return _fontFamilyName;
}
set
{
try
{
Font font1 = new Font(value, 12.0f);
_fontFamilyName = value;
font1.Dispose();
}
catch
{
_fontFamilyName = System.Drawing.FontFamily.GenericSerif.Name;
}
}
}
/// <summary>
/// Amount of random warping to apply to the Captcha text.
/// </summary>
public FontWarpFactor FontWarp
{
get
{
return _fontWarp;
}
set
{
_fontWarp = value;
}
}
/// <summary>
/// Amount of background noise to apply to the Captcha image.
/// </summary>
public BackgroundNoiseLevel BackgroundNoise
{
get
{
return _backgroundNoise;
}
set
{
_backgroundNoise = value;
}
}
public LineNoiseLevel LineNoise
{
get
{
return _lineNoise;
}
set
{
_lineNoise = value;
}
}
/// <summary>
/// A string of valid characters to use in the Captcha text.
/// A random character will be selected from this string for each character.
/// </summary>
public String TextChars
{
get
{
return _randomTextChars;
}
set
{
_randomTextChars = value;
_randomText = GenerateRandomText();
}
}
/// <summary>
/// Number of characters to use in the Captcha text.
/// </summary>
public int TextLength
{
get
{
return _randomTextLength;
}
set
{
_randomTextLength = value;
_randomText = GenerateRandomText();
}
}
/// <summary>
/// Returns the randomly generated Captcha text.
/// </summary>
public String Text
{
get
{
return _randomText;
}
}
/// <summary>
/// Width of Captcha image to generate, in pixels
/// </summary>
public int Width
{
get
{
return _width;
}
set
{
if( value <= 60 )
throw new ArgumentOutOfRangeException("width", value, "width must be greater than 60.");
_width = value;
}
}
/// <summary>
/// Height of Captcha image to generate, in pixels
/// </summary>
public int Height
{
get
{
return _height;
}
set
{
if( value <= 30 )
throw new ArgumentOutOfRangeException("height", value, "height must be greater than 30.");
_height = value;
}
}
/// <summary>
/// A semicolon-delimited list of valid fonts to use when no font is provided.
/// </summary>
public String FontWhitelist
{
get
{
return _fontWhitelist;
}
set
{
_fontWhitelist = value;
}
}
#endregion
public CaptchaImage()
{
_rand = new Random();
_fontWarp = FontWarpFactor.Low;
_backgroundNoise = BackgroundNoiseLevel.Low;
_lineNoise = LineNoiseLevel.None;
_width = 180;
_height = 50;
_randomTextLength = 5;
_randomTextChars = "ACDEFGHJKLNPQRTUVXYZ2346789";
_fontFamilyName = "";
// -- a list of known good fonts in on both Windows XP and Windows Server 2003
_fontWhitelist =
"arial;arial black;comic sans ms;courier new;estrangelo edessa;franklin gothic medium;" +
"georgia;lucida console;lucida sans unicode;mangal;microsoft sans serif;palatino linotype;" +
"sylfaen;tahoma;times new roman;trebuchet ms;verdana";
_randomText = GenerateRandomText();
_generatedAt = DateTime.Now;
_guid = Guid.NewGuid().ToString();
}
/// <summary>
/// Forces a new Captcha image to be generated using current property value settings.
/// </summary>
public Bitmap RenderImage()
{
return GenerateImagePrivate();
}
//
private static String[] ff;
/// <summary>
/// Returns a random font family from the font whitelist
/// </summary>
private String RandomFontFamily()
{
//-- small optimization so we don't have to split for each char
if( ff == null )
{
char[] charSeparators = new char[] { ';' };
ff = _fontWhitelist.Split( charSeparators, StringSplitOptions.RemoveEmptyEntries );
}
return ff[_rand.Next(0, ff.Length)];
}
/// <summary>
/// generate random text for the CAPTCHA
/// </summary>
private String GenerateRandomText()
{
System.Text.StringBuilder sb = new System.Text.StringBuilder(_randomTextLength);
int maxLength = _randomTextChars.Length;
for( int n = 0; n < _randomTextLength; n++ )
sb.Append(_randomTextChars.Substring(_rand.Next(maxLength), 1));
return sb.ToString();
}
/// <summary>
/// Returns a random point within the specified x and y ranges
/// </summary>
private PointF RandomPoint( int xmin, int xmax, int ymin, int ymax )
{
return new PointF(_rand.Next(xmin, xmax), _rand.Next(ymin, ymax));
}
/// <summary>
/// Returns a random point within the specified rectangle
/// </summary>
private PointF RandomPoint( Rectangle rect )
{
return RandomPoint(rect.Left, rect.Width, rect.Top, rect.Bottom);
}
/// <summary>
/// Returns a GraphicsPath containing the specified string and font
/// </summary>
private GraphicsPath TextPath( String s, Font f, Rectangle r )
{
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Near;
sf.LineAlignment = StringAlignment.Near;
GraphicsPath gp = new GraphicsPath();
gp.AddString(s, f.FontFamily, (int)f.Style, f.Size, r, sf);
return gp;
}
/// <summary>
/// Returns the CAPTCHA font in an appropriate size
/// </summary>
private Font GetFont()
{
float fsize = 0;
String fname = _fontFamilyName;
if( fname == "" )
{
fname = RandomFontFamily();
}
switch( this.FontWarp )
{
case FontWarpFactor.None:
fsize = Convert.ToInt32(_height * 0.7);
break;
case FontWarpFactor.Low:
fsize = Convert.ToInt32(_height * 0.8);
break;
case FontWarpFactor.Medium:
fsize = Convert.ToInt32(_height * 0.85);
break;
case FontWarpFactor.High:
fsize = Convert.ToInt32(_height * 0.9);
break;
case FontWarpFactor.Extreme:
fsize = Convert.ToInt32(_height * 0.95);
break;
}
return new Font(fname, fsize, FontStyle.Bold);
}
/// <summary>
/// Renders the CAPTCHA image
/// </summary>
private Bitmap GenerateImagePrivate()
{
Font fnt = null;
Rectangle rect;
Brush br;
Bitmap bmp = new Bitmap( _width, _height, PixelFormat.Format32bppArgb );
Graphics gr = Graphics.FromImage( bmp );
gr.SmoothingMode = SmoothingMode.AntiAlias;
// -- fill an empty white rectangle
rect = new Rectangle(0, 0, _width, _height);
br = new SolidBrush(Color.White);
gr.FillRectangle(br, rect);
int charOffset = 0;
double charWidth = _width / _randomTextLength;
Rectangle rectChar;
foreach( char c in _randomText )
{
//-- establish font and draw area
fnt = GetFont();
rectChar = new Rectangle(Convert.ToInt32(charOffset * charWidth), 0, Convert.ToInt32(charWidth), _height);
//-- warp the character
GraphicsPath gp = TextPath(c.ToString(), fnt, rectChar);
WarpText(gp, rectChar);
//-- draw the character
br = new SolidBrush(Color.Black);
gr.FillPath(br, gp);
charOffset += 1;
}
AddNoise(gr, rect);
AddLine(gr, rect);
//-- clean up unmanaged resources
fnt.Dispose();
br.Dispose();
gr.Dispose();
return bmp;
}
/// <summary>
/// Warp the provided text GraphicsPath by a variable amount
/// </summary>
private void WarpText( GraphicsPath textPath, Rectangle rect )
{
float WarpDivisor = 0;
float RangeModifier = 0;
switch( _fontWarp )
{
case FontWarpFactor.None:
return;
case FontWarpFactor.Low:
WarpDivisor = 6.0f;
RangeModifier = 1.0f;
break;
case FontWarpFactor.Medium:
WarpDivisor = 5.0f;
RangeModifier = 1.3f;
break;
case FontWarpFactor.High:
WarpDivisor = 4.5f;
RangeModifier = 1.4f;
break;
case FontWarpFactor.Extreme:
WarpDivisor = 4.0f;
RangeModifier = 1.5f;
break;
}
RectangleF rectF;
rectF = new RectangleF(Convert.ToSingle(rect.Left), 0, Convert.ToSingle(rect.Width), rect.Height);
int hrange = Convert.ToInt32(rect.Height / WarpDivisor);
int wrange = Convert.ToInt32(rect.Width / WarpDivisor);
int left = rect.Left - Convert.ToInt32(wrange * RangeModifier);
int top = rect.Top - Convert.ToInt32(hrange * RangeModifier);
int width = rect.Left + rect.Width + Convert.ToInt32(wrange * RangeModifier);
int height = rect.Top + rect.Height + Convert.ToInt32(hrange * RangeModifier);
if( left < 0 ) left = 0;
if( top < 0 ) top = 0;
if( width > this.Width ) width = this.Width;
if( height > this.Height ) height = this.Height;
PointF leftTop = RandomPoint(left, left + wrange, top, top + hrange);
PointF rightTop = RandomPoint(width - wrange, width, top, top + hrange);
PointF leftBottom = RandomPoint(left, left + wrange, height - hrange, height);
PointF rightBottom = RandomPoint(width - wrange, width, height - hrange, height);
PointF[] points = new PointF[] {leftTop, rightTop, leftBottom, rightBottom};
Matrix m = new Matrix();
m.Translate(0, 0);
textPath.Warp(points, rectF, m, WarpMode.Perspective, 0);
}
/// <summary>
/// Add a variable level of graphic noise to the image
/// </summary>
private void AddNoise( Graphics graphics1 , Rectangle rect )
{
int density = 0;
int size = 0;
switch( _backgroundNoise )
{
case BackgroundNoiseLevel.None:
return;
case BackgroundNoiseLevel.Low:
density = 30;
size = 40;
break;
case BackgroundNoiseLevel.Medium:
density = 18;
size = 40;
break;
case BackgroundNoiseLevel.High:
density = 16;
size = 39;
break;
case BackgroundNoiseLevel.Extreme:
density = 12;
size = 38;
break;
}
SolidBrush br = new SolidBrush(Color.Black);
int max = Convert.ToInt32(Math.Max(rect.Width, rect.Height) / size);
for( int i = 0; i <= Convert.ToInt32((rect.Width * rect.Height) / density); i++ )
{
graphics1.FillEllipse( br, _rand.Next(rect.Width), _rand.Next(rect.Height),
_rand.Next(max), _rand.Next(max) );
}
br.Dispose();
}
/// <summary>
/// Add variable level of curved lines to the image
/// </summary>
private void AddLine( Graphics graphics1 , Rectangle rect )
{
int length = 0;
float width = 0;
int linecount = 0;
switch( _lineNoise )
{
case LineNoiseLevel.None:
return;
case LineNoiseLevel.Low:
length = 4;
width = Convert.ToSingle(_height / 31.25);// 1.6;
linecount = 1;
break;
case LineNoiseLevel.Medium:
length = 5;
width = Convert.ToSingle(_height / 27.7777);// 1.8;
linecount = 1;
break;
case LineNoiseLevel.High:
length = 3;
width = Convert.ToSingle(_height / 25);// 2.0;
linecount = 2;
break;
case LineNoiseLevel.Extreme:
length = 3;
width = Convert.ToSingle(_height / 22.7272);// 2.2;
linecount = 3;
break;
}
PointF[] pf = new PointF[length+1];
Pen p = new Pen(Color.Black, width);
for( int l = 1; l <= linecount; l++ )
{
for( int i = 0; i <= length; i++ )
{
pf[i] = RandomPoint(rect); //int xmin, int xmax, int ymin, int ymax
}
graphics1.DrawCurve(p, pf, 1.75f);
}
p.Dispose();
}
}
}
</code>
CaptchaImageHandler.cs
<code>
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Drawing;
/// <summary>
/// Captcha image stream HttpModule. Retrieves CAPTCHA objects from cache, renders them to memory,
/// and streams them to the browser.
/// </summary>
/// <remarks>
/// You *MUST* enable this HttpHandler in your web.config, like so:
///
/// <httpHandlers>
/// <add verb="GET" path="CaptchaImage.aspx" type="WebControlCaptcha.CaptchaImageHandler, WebControlCaptcha" />
/// </httpHandlers>
///
/// Jeff Atwood
/// http://www.codinghorror.com/
/// </remarks>
namespace WebControlCaptcha_for_C_sharp
{
public class CaptchaImageHandler : IHttpHandler
{
public void ProcessRequest( HttpContext context )
{
HttpApplication app = context.ApplicationInstance;
//-- get the unique GUID of the captcha; this must be passed in via the querystring
String guid = app.Request.QueryString["guid"];
CaptchaImage ci = null;
if (guid != "")
{
if (String.IsNullOrEmpty(app.Request.QueryString["s"]))
ci = (CaptchaImage)HttpRuntime.Cache.Get(guid);
else
ci = (CaptchaImage)HttpContext.Current.Session[guid];
}
if( ci == null )
{
app.Response.StatusCode = 404;
context.ApplicationInstance.CompleteRequest();
return;
}
//-- write the image to the HTTP output stream as an array of bytes
Bitmap b = ci.RenderImage();
b.Save( app.Context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg );
b.Dispose();
app.Response.ContentType = "image/jpeg";
app.Response.StatusCode = 200;
context.ApplicationInstance.CompleteRequest();
}
public bool IsReusable
{
get
{
return true;
}
}
}
}
</code>
modified on Tuesday, June 3, 2008 3:07 AM
|
|
|
|
|
Hi,
Your Pasted code is broken.
|
|
|
|
|
Did you ever get the C# version working or do you know of where i can find a C# version?
|
|
|
|
|
can u check it and up it again in a solution package . tks a lot .
|
|
|
|
|
Sorry, I haven't web space for download ....
Would you mind I send it with Email?
|
|
|
|
|
my email address is : tcdung81@gmail.com
thank you very much my friend .
)
|
|
|
|
|
So this is how you create a custom control for asp.net.
any references that benefited you in custom control design would be appreciated. I would like to start building my own custom controls eventually. [books/articles/magazine issues ect]
some changes needed:
I'm using my own PostgreSQL SessionStateStoreProvider
for it to work your CaptchaImageHandler required the following interface:
, System.Web.SessionState.IRequiresSessionState
inside the handler you can't access the session directly from HttpContext. you need to use the one sent as the arguments to the function.
ci = (CaptchaImage)context.Session[guid];
lastly your CaptchaImage needs: [Serializable]
since the object is being saved to a session.
|
|
|
|
|
For starters, thank you very much for such a GREAT JOB of putting it together!
I've hit some problems while trying to integrate it into the .Net v3.5 site and found that quite a few folks have this issue one way or another. Now most of the issues are already covered in the other threads - all but this one
The httpHandler somehow conflicts with the web services, resulting in "Client found response content type of 'text/html; charset=utf-8', but expected 'text/xml'." message as soon as you add "<add verb="GET" path="CaptchaImage.aspx" type="WebControlCaptcha.CaptchaImageHandler, WebControlCaptcha"/>" to the list of the handlers in your Web.config. The solution turns out to be quite simple (just why so many people had this problem?) - make it location specific (or combine with the explicit authentication instructions):
<location path="CaptchaImage.aspx">
<system.web>
<httpHandlers>
<add verb="GET" path="CaptchaImage.aspx" type="WebControlCaptcha.CaptchaImageHandler, WebControlCaptcha"/>
</httpHandlers>
</system.web>
</location>
|
|
|
|
|
I am working with the VWD and Visual Basic and I am having a hard time to implement this CAPTCHA into my Website. I would like to know if it is possible and if possible, how.
Thanks
|
|
|
|
|
I just did it using VWD 2008, so the answer is yes. I have only tried it in the Pro/Team editions of VS2005, but you should be fine with VWD just as well.
|
|
|
|
|
I am using VWD Express and VB.
The problem with the coding and the article is that does not give instructions, steps by steps of how to implemented. I downloaded the code and started playing with it, but it is giving me errors, like:
Configuration Error
Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.
Parser Error Message: It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level. This error can be caused by a virtual directory not being configured as an application in IIS.
Source Error:
Line 25: </compilation>
Line 26:
Line 27: <authentication mode="Windows"/>
Line 28: </system.web>
Line 29: </configuration>
Any suggestion or help with this?
modified on Friday, February 22, 2008 11:05 AM
|
|
|
|
|
I love your blog, but why VB?
God I hate VB
Thankfully it's easy to translate.
Oh, and to the person who wants to "use it commercially" - this is not a software store... RTFA and build it yourself and use it however you want.
|
|
|
|
|
Wondering if anyone got this working using Telerik RadAjax.
The control doesn't work if you make any ajax postbacks anywhere on the page because the captcha recreates itself during the postback. It looks like the code needs a fair bit of restructuring to get this to work.
|
|
|
|
|
Does anyone have a copy of malsmith's c# version? The link is dead now.
I can provide space for it if you do.
Cheers
|
|
|
|
|
under httphandlers in web.config
<add verb="GET" path="CaptchaImage.aspx" type="WebControlCaptcha.CaptchaImageHandler, WebControlCaptcha">
|
|
|
|
|
Obviously bots roaming the web are a big issue, one of the things that can further enhance the control is a timing control. While it wont fix all situations - usually bots want to go at computer speed, using a timer to determine length of time the entry was entered from first keystroke to last keystroke can cause many bots a hastle, not too mention precious computer time. The whole reason behind bots is speed, isn't it. Slow them down and they are less likely to want to use your site.
|
|
|
|
|
Hello sir, Can this captcha control be use for commercial purposes? Thanks in advance.
John Alvin Salamat
|
|
|
|
|