利用Web Service实现验证码技术

时间:2022-12-12 21:55:40
实 例说明

字母和数字混合验证码技术是网站注册和登录模块中经常用到的验证技术,开发人员可以通过验证码技术阻止用户的非法操作。本实例将通过引用Web服务实现验证码技术,实例运行效果如图16.16 所示。


利用Web Service实现验证码技术

关 键技术
本实例中的验证码是通过在客户端生成字符串,然后调用Web服务中的方法将字符串绘制成图片再传送到客户端网页中而实现的。在绘制验证码时,主要用到Graphics 类对象的FillRectangle 和DrawString 方法,其中FillRectangle 方法是用来绘制并填充图片所在区域矩形,而DrawString 方法则是将客户端生成的字符串绘制到图片上FillRectangle
方法的语法如下:
FillRectangle(Brush brush,int x,int y,int width,int height)
参数说明

brush:确定填充特性的Brush。

x:要填充的矩形的左上角的x坐标。
y:要填充的矩形的左上角的y坐标。
width:要填充的矩形的宽度。
height:要填充的矩形的高度。
DrawString 方法的语法如下:
DrawString(string s,Font font,Brush brush,float x,float y)
参数说明
s:要绘制的字符串。
font:它定义字符串的文本格式。
brush:它确定所绘制文本的颜色和纹理。
x:所绘制文本的左上角的x坐标。
y:所绘制文本的左上角的y坐标。

在需要验证码的页面中利用Image 控件将其显示出来,在Image 控件中显示验证码的语法如下:
<asp:Image ID="Image1" src="CheckCode.aspx" runat="server" Height="21px" Width="85px" />
注意:在加入src属性时,程序会提示“属性‘src’不是元素‘Image’的有效属性”,这不影响程序执行。

设 计过程

(1)新建一个网站,将其命名为VilidateWeb,默认主页为Default.aspx。
(2)新建一个Web应用程序Ex17_09,默认主页为Default.aspx,添加新Web 窗体CheckCode.aspx,用于
输出验证码图片,添加一个Web 服务WebService.asmx。
(3)在Default.aspx 页面中添加如表16.7 所示的控件进行页面布局及功能实现。

利用Web Service实现验证码技术

(4)本实例Web服务中自定义方法主要完成验证码的绘制,主要代码如下:
/// <summary>
///生成图片验证码
/// </summary>
/// <param name="nLen">验证码的长度</param>
/// <param name="strKey">输出参数,验证码的内容</param>
/// <returns>图片字节流</returns>
[WebMethod]
public byte[] CheckCodeService(int nLen, ref string strKey)
{
int nBmpWidth = 13 * nLen + 5;
int nBmpHeight = 25;
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(nBmpWidth, nBmpHeight);
//生成随机背景颜色
int nRed, nGreen, nBlue;
//生成三原色
System.Random rd = new Random((int)System.DateTime.Now.Ticks);
nRed = rd.Next(255) % 128 + 128;
nGreen = rd.Next(255) % 128 + 128;
nBlue = rd.Next(255) % 128 + 128;
//填充背景

System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(bmp);
graph.FillRectangle(new System.Drawing.SolidBrush(System.Drawing.Color.AliceBlue), 0, 0, nBmpWidth, nBmpHeight);
//绘制干扰线条,采用比背景略深一些的颜色
int nLines = 3;
System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.FromArgb(nRed - 17, nGreen - 17, nBlue - 17), 2);
for (int a = 0; a < nLines; a++)
{
int x1 = rd.Next(nBmpWidth) ;
int y1 = rd.Next(nBmpHeight);
int x2 = rd.Next(nBmpWidth) ;
int y2 = rd.Next(nBmpHeight) ;
graph.DrawLine(pen, x1, y1, x2, y2);
}
//画图片的前景噪音点
for (int i = 0; i < 100; i++)
{
int x = rd.Next(bmp.Width);
int y = rd.Next(bmp.Height);
bmp.SetPixel(x, y, System.Drawing.Color.FromArgb(rd.Next( )));
}
//确定字体
System.Drawing.Font font = new System.Drawing.Font("Courier New",14 + rd.Next( ) % 4,System.Drawing.FontStyle.Bold);
System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(
new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Color.Blue, System.Drawing.Color. DarkRed, 1.2f, true);
graph.DrawString(strKey,font,brush,2,2);
//输出字节流
System.IO.MemoryStream stream = new System.IO.MemoryStream( );
bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
bmp.Dispose( );
graph.Dispose( );
byte[] byteReturn = stream.ToArray( );
stream.Close( );
return byteReturn;
}
在CheckCode.aspx 页面中定义一个CheckCode 方法用于生成随机字符串,代码如下:


public string CheckCode(int length)
{
string strResult = "";
//采用的字符集,可以随机拓展,并可以控制字符出现的几率
string strCode = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
Random rd = new Random( );
for (int i = 0; i < length; i++)
{
char c = strCode[rd.Next(strCode.Length)];
//随机获取字符
strResult += c.ToString( );
}
Session["CheckCode"] = strResult;
return strResult;
}
在页面CheckCode.aspx 中显示验证码的代码如下:
protected void Page_Load(object sender, EventArgs e)
{
WebService image = new WebService( );
int length = 4;
string strKey = CheckCode(length);
byte[] data = image.CheckCodeService(length, ref strKey);
Response.OutputStream.Write(data, 0, data.Length);
}

秘 笈心法
心法领悟492:Web Service 开发中注意的问题——谨慎地抛出异常。
对于Web Service中的任何异常都应该进行相应的处理。可以简单归纳为以下两种情况。
第一种情况是接口返回值是简单类型,例如,bool 型,只有true 和false 两种情况,不抛出异常怎么办?


选择有两种,一是抛出异常,二是改变接口,返回int 用1 和0对应ture 和false,用-1对应系统异常。

第二种情况是接口返回值是复杂对象,可以通过参数out string exceptionInfo 来返回异常信息。