Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
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"); }
|