Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Captcha






Для создания капчи, мы используем отдельный класс, который создаст нам картинку с цифрами и выведет как картинку. Сами цифры будут сохранены в сессионные данные. Про сессию мы дальше еще поговорим. Сейчас надо знать только, что сессия однозначно определяет пользователя.

Создадим Tools/CaptchaImage.cs

/// < summary>

/// Генерация капчи

/// < /summary>

public class CaptchaImage

{

public const string CaptchaValueKey = " CaptchaImageText";

 

public string Text

{

get { return text; }

}

public Bitmap Image

{

get { return image; }

}

public int Width

{

get { return width; }

}

public int Height

{

get { return height; }

}

 

// Internal properties.

private string text;

private int width;

private int height;

private string familyName;

private Bitmap image;

 

// For generating random numbers.

private Random random = new Random();

 

public CaptchaImage(string s, int width, int height)

{

text = s;

SetDimensions(width, height);

GenerateImage();

}

 

public CaptchaImage(string s, int width, int height, string familyName)

{

text = s;

SetDimensions(width, height);

SetFamilyName(familyName);

GenerateImage();

}

 

// ====================================================================

// This member overrides Object.Finalize.

// ====================================================================

~CaptchaImage()

{

Dispose(false);

}

 

// ====================================================================

// Releases all resources used by this object.

// ====================================================================

public void Dispose()

{

GC.SuppressFinalize(this);

Dispose(true);

}

 

// ====================================================================

// Custom Dispose method to clean up unmanaged resources.

// ====================================================================

protected virtual void Dispose(bool disposing)

{

if (disposing)

// Dispose of the bitmap.

image.Dispose();

}

 

// ====================================================================

// Sets the image aWidth and aHeight.

// ====================================================================

private void SetDimensions(int aWidth, int aHeight)

{

// Check the aWidth and aHeight.

if (aWidth < = 0)

throw new ArgumentOutOfRangeException(" aWidth", aWidth, " Argument out of range, must be greater than zero.");

if (aHeight < = 0)

throw new ArgumentOutOfRangeException(" aHeight", aHeight, " Argument out of range, must be greater than zero.");

width = aWidth;

height = aHeight;

}

 

// ====================================================================

// Sets the font used for the image text.

// ====================================================================

private void SetFamilyName(string aFamilyName)

{

// If the named font is not installed, default to a system font.

try

{

Font font = new Font(aFamilyName, 12F);

familyName = aFamilyName;

font.Dispose();

}

catch (Exception)

{

familyName = FontFamily.GenericSerif.Name;

}

}

 

// ====================================================================

// Creates the bitmap image.

// ====================================================================

private void GenerateImage()

{

// Create a new 32-bit bitmap image.

Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);

 

// Create a graphics object for drawing.

Graphics g = Graphics.FromImage(bitmap);

g.SmoothingMode = SmoothingMode.AntiAlias;

Rectangle rect = new Rectangle(0, 0, width, height);

 

// Fill in the background.

HatchBrush hatchBrush = new HatchBrush(HatchStyle.SmallConfetti, Color.LightGray, Color.White);

g.FillRectangle(hatchBrush, rect);

 

// Set up the text font.

SizeF size;

float fontSize = rect.Height + 1;

Font font;

// Adjust the font size until the text fits within the image.

do

{

fontSize--;

font = new Font(familyName, fontSize, FontStyle.Bold);

size = g.MeasureString(text, font);

} while (size.Width > rect.Width);

 

// Set up the text format.

StringFormat format = new StringFormat();

format.Alignment = StringAlignment.Center;

format.LineAlignment = StringAlignment.Center;

 

// Create a path using the text and warp it randomly.

GraphicsPath path = new GraphicsPath();

path.AddString(text, font.FontFamily, (int)font.Style, font.Size, rect, format);

float v = 4F;

PointF[] points =

{

new PointF(random.Next(rect.Width) / v, random.Next(rect.Height) / v),

new PointF(rect.Width - random.Next(rect.Width) / v, random.Next(rect.Height) / v),

new PointF(random.Next(rect.Width) / v, rect.Height - random.Next(rect.Height) / v),

new PointF(rect.Width - random.Next(rect.Width) / v, rect.Height - random.Next(rect.Height) / v)

};

Matrix matrix = new Matrix();

matrix.Translate(0F, 0F);

path.Warp(points, rect, matrix, WarpMode.Perspective, 0F);

 

// Draw the text.

hatchBrush = new HatchBrush(HatchStyle.LargeConfetti, Color.LightGray, Color.DarkGray);

g.FillPath(hatchBrush, path);

 

// Add some random noise.

int m = Math.Max(rect.Width, rect.Height);

for (int i = 0; i < (int)(rect.Width * rect.Height / 30F); i++)

{

int x = random.Next(rect.Width);

int y = random.Next(rect.Height);

int w = random.Next(m / 50);

int h = random.Next(m / 50);

g.FillEllipse(hatchBrush, x, y, w, h);

}

 

// Clean up.

font.Dispose();

hatchBrush.Dispose();

g.Dispose();

 

// Set the image.

image = bitmap;

}

}

Суть такова, что в свойство Image генерируется картинка, состоящая из цифр (которые как бы сложно распознать) методом GenerateImage().

 

Теперь сделаем метод вывода UserController.Captcha():

 

public ActionResult Captcha()

{

Session[CaptchaImage.CaptchaValueKey] = new Random(DateTime.Now.Millisecond).Next(1111, 9999).ToString();

var ci = new CaptchaImage(Session[CaptchaImage.CaptchaValueKey].ToString(), 211, 50, " Arial");

 

// Change the response headers to output a JPEG image.

this.Response.Clear();

this.Response.ContentType = " image/jpeg";

 

// Write the image to the response stream in JPEG format.

ci.Image.Save(this.Response.OutputStream, ImageFormat.Jpeg);

 

// Dispose of the CAPTCHA image object.

ci.Dispose();

return null;

}

 

Что здесь происходит:

· В сессии создаем случайное число от 1111 до 9999.

· Создаем в ci объект CatchaImage

· Очищаем поток вывода

· Задаем header для mime-типа этого http-ответа будет “image/jpeg” т.е. картинка формата jpeg.

· Сохраняем bitmap в выходной поток с форматом ImageFormat.Jpeg

· Освобождаем ресурсы Bitmap

· Возвращаем null, так как основная информация уже передана в поток вывода

 

Запрашиваем картинку из Register.cshtml:

< label class=" control-label" for=" FirstName" >

< img src=" @Url.Action(" Captcha", " User")" alt=" captcha" />

< /label>

 

Проверка:

if (userView.Captcha! = (string)Session[CaptchaImage.CaptchaValueKey])

{

ModelState.AddModelError(" Captcha", " Текст с картинки введен неверно");

}

 

Вот и всё, закончили. Добавляем создание записи и проверяем, как она работает:

if (ModelState.IsValid)[c1]

{

var user = (User)ModelMapper.Map(userView, typeof(UserView), typeof(User));

 

Repository.CreateUser(user);

return RedirectToAction(" Index");

}


 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.