Ejemplo de código BotDetect ASP.NET MVC CAPTCHA VB.NET
Este ejemplo de BotDetect ASP.NET MVC muestra como utilizar BotDetect ASP.NET CAPTCHA para proteger aplicaciones ASP.NET MVC. Partiendo por el proyecto estándar de ASP.NET MVC creado desde Visual Studio (File > New Project > Visual VB.NET > Web > ASP.NET MVC Web Application), modificaremos la página Register.aspx para incluir nuestro CAPTCHA, asegurando que sólo sean humanos los que puedan crear cuentas de usuario.
Cómo el proyecto de inicio de ASP.NET MVC contiene mucho código, no incluiremos todo el mismo en esta explicación, sólo las partes que debemos modificar para lograr la inclusión de nuestro BotDetect CAPTCHA a la página de registro. Considere que este ejemplo requiere la BotDetect ASP.NET CAPTCHA en su versión 2.0.13 o superior.
- Ubicación de los archivos del proyecto
- Views/Account/Register.aspx
- Attributes/CaptchaValidationAttribute.vb
- Controllers/AccountController.vb
- Views/Shared/Site.Master
- Views/Shared/HtmlHelper.vb
- Content/BotDetectLayout.css
- Content/BotDetectScripts.js
- Global.asax.vb
- Web.config
Ubicación de los archivos del proyecto
Por defecto, los archivos de este ejemplo se encuentran en:
C:\Program Files\Lanapsoft\BotDetect\ASP.NET 2.0\v2.0\Samples\VBNetBotDetect2MvcDemo\.
También puede acceder a este ejemplo desde el menú inicio:
Programs > Lanapsoft > BotDetect > ASP.NET 2.0 > v2.0 > Samples > VB.Net BotDetect ASP.NET MVC CAPTCHA Sample.
Views/Account/Register.aspx
Código fuente completo
<%@ Page Language="VB" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage" %>
<%@ Import Namespace="VbNetBotDetectMvcDemo" %>
<asp:Content ID="registerHead" ContentPlaceHolderID="head"
runat="server">
<title>Register</title>
</asp:Content>
<asp:Content ID="registerContent" ContentPlaceHolderID="MainContent"
runat="server">
<h2>Account Creation</h2>
<p>
Use the form below to create a new account.
</p>
<p>
Passwords are required to be a minimum of <%=Html.Encode( _
ViewData("PasswordLength"))%> characters in length.
</p>
<%= Html.ValidationSummary() %>
<% Using Html.BeginForm() %>
<div>
<fieldset>
<legend>Account Information</legend>
<p>
<label for="username">Username:</label>
<%= Html.TextBox("username") %>
<%= Html.ValidationMessage("username") %>
</p>
<p>
<label for="email">Email:</label>
<%= Html.TextBox("email") %>
<%= Html.ValidationMessage("email") %>
</p>
<p>
<label for="password">Password:</label>
<%= Html.Password("password") %>
<%= Html.ValidationMessage("password") %>
</p>
<p>
<label for="confirmPassword">Confirm password:</label>
<%= Html.Password("confirmPassword") %>
<%= Html.ValidationMessage("confirmPassword") %>
</p>
<%
Dim registrationCaptcha As Lanap.BotDetect.MvcCaptcha
registrationCaptcha = _
New Lanap.BotDetect.MvcCaptcha("RegistrationCaptcha")
registrationCaptcha.TextStyle = _
Lanap.BotDetect.TextStyleEnum.Lego
registrationCaptcha.CodeLength = 4
registrationCaptcha.ImageSize = _
New System.Drawing.Size(245, 50)
registrationCaptcha.SaveProperties()
If (Not registrationCaptcha.IsSolved) Then
%>
<%= Html.Captcha(registrationCaptcha) %>
<p>
<label for="captchaCode">Type the characters you see
in the picture:</label>
<%= Html.TextBox("captchaCode") %>
<%= Html.ValidationMessage("captchaCode")%>
</p>
<script type="text/javascript">
function LBD_ClearUserInput() {
var LBD_textBox = document.getElementById('captchaCode');
if(LBD_textBox) {
LBD_textBox.value = '';
}
}
LBD_RegisterHandler('PreReloadCaptchaImage',
LBD_ClearUserInput);
</script>
<%
End If
%>
<p>
<input type="submit" value="Register" />
</p>
</fieldset>
</div>
<% End Using %>
</asp:Content>
Explicación
En vez de usar el control Lanap.BotDetect.Captcha que usamos para los formularios web de aplicaciones de ASP.NET, usaremos una clase especializada llamada Lanap.BotDetect.MvcCaptcha, y estableceremos sus propiedades directamente en el formulario del código mismo. Note que luego de configurar algunas propiedades, se debe llamar al método SaveProperties - de otra forma esta configuración no será almacenada de forma persistente.
Luego de inicializar la instancia de MvcCaptcha, pasaremos como parámetro un elemento HtmlHelper usado para generar el MvcCaptcha, pero sólo si no ha sido correctamente validado. En otras palabras, si el usuario escribe el Captcha correctamente, él ya no es considerado como posible "bot" automatizado, y un nuevo Captcha ya no es mostrado incluso para el mismo usuario en otras validaciones en que falle (como correo electrónico).
Es de considerar, que debimos utilizar <%@ Import, pues HtmlHelper debía ser definido.
Attributes/CaptchaValidationAttribute.vb
Código fuente completo
Imports System
Imports System.Web.Mvc
Imports Lanap.BotDetect
Namespace Attributes
<AttributeUsage(AttributeTargets.Method, AllowMultiple:=False, _
Inherited:=False)> _
Public NotInheritable Class CaptchaValidationAttribute
Inherits ActionFilterAttribute
Public Sub New()
Me.New("captchaCode", "RegistrationCaptcha")
End Sub
Public Sub New(ByVal inputfield As String, _
ByVal captchaId As String)
mField = inputfield
mCaptchaId = captchaId
End Sub
Private mField As String
Private mCaptchaId As String
Public Overrides Sub OnActionExecuting(ByVal filterContext As _
ActionExecutingContext)
' make sure the captcha valid key is not contained in the
' route data
If (filterContext.RouteData.Values.ContainsKey( _
"captchaValid")) Then
filterContext.RouteData.Values.Remove("captchaValid")
End If
If (String.IsNullOrEmpty(mCaptchaId)) Then
filterContext.RouteData.Values.Add("captchaValid", _
False)
Return
End If
Dim captchaCode As String
captchaCode = filterContext.HttpContext.Request.Form(mField)
' Captcha validation
Dim captchaInstance As MvcCaptcha
captchaInstance = New MvcCaptcha(mCaptchaId)
Dim captchaInstanceId As String
captchaInstanceId = _
filterContext.HttpContext.Request.Form( _
captchaInstance.CaptchaIdKey)
' the Captcha is only validated if it was included on
' the page
If (Not (String.IsNullOrEmpty(captchaInstanceId))) Then
If ((captchaInstance.Validate(captchaCode, _
captchaInstanceId))) Then
filterContext.RouteData.Values.Add("captchaValid", _
True)
Return
End If
End If
filterContext.RouteData.Values.Add("captchaValid", False)
Return
End Sub
End Class
End Namespace
Explicación
Para validar el CAPTCHA ingresado por el usuario, crearemos una nueva instancia de MvcCaptcha con el mismo nombre con el que fue añadido a Register.aspx page ("RegistrationCaptcha"), y la validaremos.
Comprobando la existencia del campo oculto llamado captchaInstanceId, podemos detectar la presencia del Captcha mismo en la página indirectamente. Esto nos permite validar el Captcha sólo en las ocasiones en que fue resuelto por el usuario.
El nombre usado para cada Captcha nos permite tener diferentes Captchas y validarlos de forma separada - por ejemplo, podríamos tener un Captcha en PostComment.aspx enlazado con otro controlador usando una acción llamada PostComment, y podriamos usar otro Captcha con otro nombre ("CommentCaptcha") para distinguirlos.
Controllers/AccountController.vb
Código fuente completo
Cómo este código fuente contiene un montón de código generado por el entorno de desarrollo, sólo mostraremos algunas partes que requieren modificaciones para que BotDetect CAPTCHA funcione correctamente.
<AcceptVerbs(HttpVerbs.Post)> _
<CaptchaValidation("captchaCode", "RegistrationCaptcha")> _
Function Register(ByVal userName As String, ByVal email As String,
ByVal password As String, ByVal confirmPassword As String,
ByVal captchaCode As String) As ActionResult
ViewData("Title") = "Register"
ViewData("PasswordLength") = MembershipService.MinPasswordLength
If ValidateRegistration(userName, email, password, confirmPassword,
captchaCode) Then
' Attempt to register the user
Dim createStatus As MembershipCreateStatus = _
MembershipService.CreateUser(userName, password, email)
If createStatus = MembershipCreateStatus.Success Then
FormsAuth.SignIn(userName, False)
Return RedirectToAction("Index", "Home")
Else
ModelState.AddModelError("_FORM", _
ErrorCodeToString(createStatus))
End If
End If
Return View()
End Function
Private Function ValidateRegistration(ByVal userName As String, _
ByVal email As String, ByVal password As String, _
ByVal confirmPassword As String, ByVal captchaCode As String) _
As Boolean
If String.IsNullOrEmpty(userName) Then
ModelState.AddModelError("username", _
"You must specify a username.")
End If
If String.IsNullOrEmpty(email) Then
ModelState.AddModelError("email", _
"You must specify an email address.")
End If
If password Is Nothing OrElse _
password.Length < MembershipService.MinPasswordLength Then
ModelState.AddModelError("password", _
String.Format(CultureInfo.CurrentCulture, _
"You must specify a password of {0} or more characters.", _
MembershipService.MinPasswordLength))
End If
If Not String.Equals(password, confirmPassword, _
StringComparison.Ordinal) Then
ModelState.AddModelError("_FORM", _
"The new password and confirmation password do not match.")
End If
'Captcha validation
If (Not (CType(Me.RouteData.Values("captchaValid"), Boolean))) Then
ModelState.AddModelError("captchaCode", _
"The CAPTCHA code was incorrect!")
End If
Return ModelState.IsValid
End Function
Explicación
Añadimos un nuevo recuadro de texto para que el usuario ingrese el CAPTCHA, por lo que debemos modificar los métodos Register y ValidateRegistration aceptando un string adicional - captchaCode. En el método ValidateRegistration, añadimos una comprobación del CAPTCHA mismo.
Views/Shared/Site.Master
Código fuente completo
<%@ Master Language="VB" Inherits="System.Web.Mvc.ViewMasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1" />
<asp:ContentPlaceHolder ID="head" runat="server">
<title></title>
</asp:ContentPlaceHolder>
<asp:PlaceHolder runat="server" id="includes">
<link href="<%= VirtualPathUtility.ToAbsolute(
"~/Content/Site.css") %>" rel="stylesheet" type="text/css" />
<link href="<%= VirtualPathUtility.ToAbsolute(
"~/Content/BotDetectLayout.css") %>" rel="stylesheet"
type="text/css" />
<script type='text/javascript' src='<%= VirtualPathUtility.
ToAbsolute("~/Content/BotDetectScripts.js") %>'></script>
</asp:PlaceHolder>
</head>
<body>
<div class="page">
<div id="header">
<div id="title">
<h1>My MVC Application</h1>
</div>
<div id="logindisplay">
<% Html.RenderPartial("LogOnUserControl"); %>
</div>
<div id="menucontainer">
<ul id="menu">
<li><%= Html.ActionLink("Home", "Index", "Home")%></li>
<li><%= Html.ActionLink("About", "About", "Home")%></li>
</ul>
</div>
</div>
<div id="main">
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
<div id="footer">
</div>
</div>
</div>
</body>
</html>
Explicación
La única modificación de la "Master page" es la incorporación de código de lado del cliente de BotDetect y declaraciones de CSS, que deben ser copiadas a la carpeta Content. Todas incluyen la ruta completa (para no tener problemas con niveles superiores de la jerarquía), incorporados dentro de un PlaceHolder para evitar problemas existentes con el despliegue de ASP.NET MVC.
Views/Shared/HtmlHelper.vb
Código fuente completo
Imports System.Runtime.CompilerServices
Public Module CaptchaExtensions
<Extension()> _
Public Function Captcha(ByVal helper As HtmlHelper, _
ByRef captchaInstance As Object) As String
Dim captchaInst As Lanap.BotDetect.MvcCaptcha
captchaInst = CType(captchaInstance, Lanap.BotDetect.MvcCaptcha)
Dim markupBuilder As StringBuilder
markupBuilder = New StringBuilder
markupBuilder.Append("<div class='LBD_CaptchaDiv' style='width:")
markupBuilder.Append(captchaInst.ImageSize.Width + 28)
markupBuilder.Append("px; height: ")
markupBuilder.Append(captchaInst.ImageSize.Height + 10)
markupBuilder.Append("px'>" & ControlChars.NewLine)
markupBuilder.Append("<div class='LBD_CaptchaImage' style='width:")
markupBuilder.Append(captchaInst.ImageSize.Width)
markupBuilder.Append("px; height: ")
markupBuilder.Append(captchaInst.ImageSize.Height)
markupBuilder.Append("px '>" & ControlChars.NewLine)
markupBuilder.Append("<img id='")
markupBuilder.Append(captchaInst.CaptchaId)
markupBuilder.Append("_CaptchaImage' src='")
markupBuilder.Append(captchaInst.ImageLink)
markupBuilder.Append("' alt='CAPTCHA Code Image' />" & _
ControlChars.NewLine)
markupBuilder.Append("</div>" & ControlChars.NewLine)
markupBuilder.Append("<div class='LBD_CaptchaIcons'>")
markupBuilder.Append("<a href="")
markupBuilder.Append(captchaInst.SoundLink)
markupBuilder.Append("' onclick='LBD_LoadSound(""")
markupBuilder.Append(captchaInst.CaptchaId)
markupBuilder.Append("_SoundPlaceholder"", """)
markupBuilder.Append(captchaInst.SoundLink)
markupBuilder.AppendFormat(""");this.blur();return false;'>
<img src='{0}' alt='Play Sound' /></a>", _
VirtualPathUtility.ToAbsolute("~/Content/Speaker.gif"))
markupBuilder.Append("<a href="#" onclick='LBD_ReloadImage(""")
markupBuilder.Append(captchaInst.CaptchaId)
markupBuilder.AppendFormat("_CaptchaImage"");this.blur();
return false;'><img src='{0}' alt='Change the code' />
</a>", VirtualPathUtility.ToAbsolute("~/Content/Refresh.gif"))
markupBuilder.Append("<div id='")
markupBuilder.Append(captchaInst.CaptchaId)
markupBuilder.Append("_SoundPlaceholder' class='LBD_placeholder'>
</div>")
markupBuilder.Append("</div>" & ControlChars.NewLine)
markupBuilder.Append("</div>" & ControlChars.NewLine)
markupBuilder.Append("<input type='hidden' ")
markupBuilder.Append("id='")
markupBuilder.Append(captchaInst.CaptchaIdKey)
markupBuilder.Append("' ")
markupBuilder.Append("name='")
markupBuilder.Append(captchaInst.CaptchaIdKey)
markupBuilder.Append("' ")
markupBuilder.Append("value='")
markupBuilder.Append(captchaInst.CurrentInstanceId)
markupBuilder.Append("' />")
Return markupBuilder.ToString()
End Function
End Module
Explicación
En este archivo, incluimos un método simple llamado MvcCaptcha para generar todos los formularios ASP.NET MVC. Note que el ícono del altavoz y recarga fueron cargados desde el directorio Content.
Content/BotDetectLayout.css
Código fuente completo
.LBD_CaptchaDiv {
padding: 0 !important;
margin: 20px 0 0 10px;
overflow: visible !important;
}
*html .LBD_CaptchaDiv {
margin-bottom: -3px !important;
overflow: hidden !important;
}
.LBD_CaptchaDiv .LBD_CaptchaImage
{
float: left !important;
margin: 0 !important;
padding: 0 !important;
}
.LBD_CaptchaDiv .LBD_CaptchaIcons
{
width: 22px !important;
float: right !important;
text-align: left !important;
margin: 0 !important;
padding: 0 !important;
margin-bottom: -4px !important;
margin-top: -1px !important;
margin-right: 2px !important;
}
*html .LBD_CaptchaDiv .LBD_CaptchaIcons
{
margin-right: 1px !important;
}
.LBD_CaptchaDiv .LBD_CaptchaIcons a
{
margin: 0 !important;
padding: 0 !important;
display: block !important;
background-color: transparent !important;
text-decoration: none !important;
border: none !important;
}
.LBD_CaptchaDiv .LBD_CaptchaIcons a:focus,
.LBD_CaptchaDiv .LBD_CaptchaIcons a:active
{
border: none !important;
-moz-outline:none !important;
}
.LBD_CaptchaDiv .LBD_CaptchaIcons a img
{
border: 0 !important;
margin: 0 !important;
padding: 0 !important;
margin-top: 2px !important;
margin-bottom: 3px !important;
display: block !important;
}
.LBD_CaptchaDiv .LBD_CaptchaIcons a:focus img,
.LBD_CaptchaDiv .LBD_CaptchaIcons a:active img
{
border: 1px dotted #333 !important;
margin: 0 !important;
padding: 0 !important;
margin-top: 1px !important;
margin-bottom: 1px !important;
display: block !important;
}
*html .LBD_CaptchaDiv .LBD_CaptchaIcons a:focus img,
*html .LBD_CaptchaDiv .LBD_CaptchaIcons a:active img
{
border: 1px solid #999 !important;
margin-bottom: 3px !important;
}
*:first-child+html .LBD_CaptchaDiv .LBD_CaptchaIcons a:focus img,
*:first-child+html .LBD_CaptchaDiv .LBD_CaptchaIcons a:active img
{
border: 1px solid #999 !important;
}
.LBD_CaptchaDiv .LBD_CaptchaIcons .LBD_placeholder
{
visibility: hidden !important;
width: 0 !important;
height: 0 !important;
}
*html .LBD_CaptchaDiv .LBD_CaptchaIcons .LBD_placeholder
{
display: none !important;
}
*:first-child+html .LBD_CaptchaDiv .LBD_CaptchaIcons .LBD_placeholder
{
display: none !important;
}
Explicación
En las aplicaciones ASP.NET, las declaraciones CSS usadas por el control BotDetect Captcha control se incluyen dentro del ensamblado Lanap.BotDetect.dll y incluyen recursos web dentro. Como este alcance no está disponible en ASP.NET MVC, el mismo CSS debe ser declarado manualmente en un archivo .css externo.
Content/BotDetectScripts.js
Código fuente completo
var LBD_ImgId = null;
var LBD_Img = null;
var LBD_NewImg = null;
var LBD_Parent = null;
var LBD_Prompt = null;
var LBD_Timer = null;
var LBD_TimerTicks = 0;
function LBD_LoadSound(soundPlaceholderId, soundLink)
{
if(document.getElementById)
{
var i = soundLink.indexOf('&d=');
if (-1 != i) {
soundLink = soundLink.substring(0, i);
}
soundLink = soundLink + '&d=' + LBD_GetTimestamp();
if ((-1 == soundLink.indexOf('&e=')) &&
(document.location.protocol == "https:")) {
soundLink = soundLink + '&e=1';
}
var placeholder = document.getElementById(soundPlaceholderId);
var objectSrc = "<object id='captchaSound'
classid='clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95'
height='0' width='0' style='width:0; height:0;'>
<param name='AutoStart' value='1' />
<param name='Volume' value='0' />
<param name='PlayCount' value='1' />
<param name='FileName' value='" + soundLink + "' />
<embed id='captchaSoundEmbed' src='"+ soundLink +
"' autoplay='true' hidden='true' volume='100'
type='"+ LBD_GetMimeType() +"' style='display:inline;' />
</object>";
placeholder.innerHTML = "";
placeholder.innerHTML = objectSrc;
}
}
function LBD_GetTimestamp() {
var d = new Date();
var t = d.getTime() + (d.getTimezoneOffset() * 60000);
return t;
}
function LBD_GetMimeType()
{
var mimeType = "audio/x-wav";
return mimeType;
}
function LBD_ReloadImage(imgId)
{
if(imgId)
{
LBD_ImgId = imgId;
LBD_Img = document.getElementById(LBD_ImgId);
var src = LBD_Img.src;
var i = src.indexOf('&d=');
if (-1 != i) {
src = src.substring(0, i);
}
var newSrc = src + '&d=' + LBD_GetTimestamp();
LBD_NewImg = document.createElement('img');
LBD_NewImg.onload = LBD_ShowImage;
LBD_NewImg.id = LBD_Img.id;
LBD_NewImg.alt = LBD_Img.alt;
LBD_NewImg.src = newSrc;
LBD_Prompt = document.createElement('span');
LBD_Prompt.appendChild(document.createTextNode('.'));
LBD_PreReloadImage();
LBD_Parent = LBD_Img.parentNode;
LBD_Parent.removeChild(LBD_Img);
LBD_Parent.appendChild(LBD_Prompt);
LBD_ShowProgress()
}
}
function LBD_ShowProgress()
{
if((LBD_Prompt)&&(LBD_TimerTicks < 100))
{
LBD_TimerTicks = LBD_TimerTicks + 1;
if(0 == LBD_TimerTicks % 5)
{
LBD_Prompt.firstChild.nodeValue = '.';
}
else
{
LBD_Prompt.firstChild.nodeValue =
LBD_Prompt.firstChild.nodeValue + '.';
}
LBD_Timer = setTimeout("LBD_ShowProgress()", 250);
}
else
{
clearTimeout(LBD_Timer);
LBD_TimerTicks = 0;
}
}
function LBD_ShowImage()
{
if(LBD_NewImg && LBD_Parent && LBD_Prompt)
{
LBD_Parent.removeChild(LBD_Prompt);
LBD_Parent.appendChild(LBD_NewImg);
LBD_Prompt = null;
LBD_PostReloadImage();
}
}
function LBD_PreReloadImage() {}
function LBD_PostReloadImage() {}
function LBD_RegisterHandler(eventName, userHandler)
{
switch(eventName.toLowerCase())
{
case 'prereloadcaptchaimage':
var LBD_OldHandler = LBD_PreReloadImage;
LBD_PreReloadImage = function() {
LBD_OldHandler();
userHandler();
}
break;
case 'postreloadcaptchaimage':
var oldHandler = LBD_PostReloadImage;
LBD_PostReloadImage = function() {
LBD_OldHandler();
userHandler();
}
break;
}
}
if ((typeof(Sys) != "undefined") &&
(typeof(Sys.Application) != "undefined")) {
Sys.Application.notifyScriptLoaded();
}
Explicación
En las aplicaciones ASP.NET, las rutinas de lado del cliente en Javascript usadas por el control BotDetect Captcha control se incluyen dentro del ensamblado Lanap.BotDetect.dll y incluyen recursos web dentro. Como este alcance no está disponible en ASP.NET MVC, el mismo código de Javascript debe ser declarado manualmente en un archivo .js externo.
Global.asax.vb
Código fuente completo
' Note: For instructions on enabling IIS6 or IIS7 classic mode,
' visit http://go.microsoft.com/?LinkId=9394802
Public Class MvcApplication
Inherits System.Web.HttpApplication
Shared Sub RegisterRoutes(ByVal routes As RouteCollection)
routes.IgnoreRoute("{resource}.axd/{*pathInfo}")
' MapRoute takes the following parameters, in order:
' (1) Route name
' (2) URL with parameters
' (3) Parameter defaults
routes.MapRoute( _
"Default", _
"{controller}/{action}/{id}", _
New With {.controller = "Account", .action = "Register", .id = ""} _
)
routes.MapRoute( _
"Root", _
"", _
New With {.controller = "Account", .action = "Register", .id = ""} _
)
End Sub
Sub Application_Start()
RegisterRoutes(RouteTable.Routes)
End Sub
End Class
Explicación
Para registrar la acción por defecto de la aplicación, "Register", debemos (para que el CAPTCHA sea visible automáticamente al inicio de la aplicación misma) debemos cambiar la ruta del método RegisterRoutes.
Web.config
Código fuente completo
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="system.web.extensions" type="
System.Web.Configuration.SystemWebExtensionsSectionGroup,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35">
<sectionGroup name="scripting" type="System.Web.
Configuration.ScriptingSectionGroup, System.Web.Extensions,
Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35">
<section name="scriptResourceHandler" type="System.Web.
Configuration.ScriptingScriptResourceHandlerSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication"/>
<sectionGroup name="webServices" type="System.Web.
Configuration.ScriptingWebServicesSectionGroup,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35">
<section name="jsonSerialization" type="System.Web.
Configuration.ScriptingJsonSerializationSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="Everywhere" />
<section name="profileService" type="System.Web.
Configuration.ScriptingProfileServiceSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication" />
<section name="authenticationService" type="System.Web.
Configuration.ScriptingAuthenticationServiceSection,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication" />
<section name="roleService" type="System.Web.Configuration.
ScriptingRoleServiceSection, System.Web.Extensions,
Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" requirePermission="false"
allowDefinition="MachineToApplication" />
</sectionGroup>
</sectionGroup>
</sectionGroup>
</configSections>
<appSettings>
<add key="LBD_RequestPath" value="LanapCaptcha.axd" />
</appSettings>
<connectionStrings>
<add name="ApplicationServices" connectionString="
data source=.\SQLEXPRESS;Integrated Security=SSPI;
AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient"/>
</connectionStrings>
<system.web>
<compilation debug="false">
<assemblies>
<add assembly="System.Core, Version=3.5.0.0,
Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Web.Extensions, Version=3.5.0.0,
Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Web.Abstractions, Version=3.5.0.0,
Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Web.Routing, Version=3.5.0.0,
Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Web.Mvc, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0,
Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Xml.Linq, Version=3.5.0.0,
Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Data.Linq, Version=3.5.0.0,
Culture=neutral, PublicKeyToken=B77A5C561934E089" />
</assemblies>
</compilation>
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" />
</authentication>
<membership>
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider,
System.Web, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="ApplicationServices"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="false"
requiresUniqueEmail="false"
passwordFormat="Hashed"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="6"
minRequiredNonalphanumericCharacters="0"
passwordAttemptWindow="10"
passwordStrengthRegularExpression=""
applicationName="/"
/>
</providers>
</membership>
<profile>
<providers>
<clear/>
<add name="AspNetSqlProfileProvider"
type="System.Web.Profile.SqlProfileProvider, System.Web,
Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="ApplicationServices"
applicationName="/"
/>
</providers>
</profile>
<roleManager enabled="false">
<providers>
<clear />
<add connectionStringName="ApplicationServices"
applicationName="/" name="AspNetSqlRoleProvider"
type="System.Web.Security.SqlRoleProvider, System.Web,
Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a" />
<add applicationName="/" name="AspNetWindowsTokenRoleProvider"
type="System.Web.Security.WindowsTokenRoleProvider,
System.Web, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</roleManager>
<pages>
<controls>
<add tagPrefix="asp" namespace="System.Web.UI"
assembly="System.Web.Extensions, Version=3.5.0.0,
Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add tagPrefix="asp" namespace="System.Web.UI.WebControls"
assembly="System.Web.Extensions, Version=3.5.0.0,
Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</controls>
<namespaces>
<add namespace="System.Web.Mvc"/>
<add namespace="System.Web.Mvc.Ajax"/>
<add namespace="System.Web.Mvc.Html"/>
<add namespace="System.Web.Routing"/>
<add namespace="System.Linq"/>
<add namespace="System.Collections.Generic"/>
</namespaces>
</pages>
<sessionState mode="InProc" cookieless="AutoDetect" timeout="20"
sessionIDManagerType="Lanap.BotDetect.Persistence.
CustomSessionIDManager, Lanap.BotDetect" />
<customErrors mode="On" defaultRedirect="~/Content/Error.html"/>
<httpHandlers>
<remove verb="*" path="*.asmx"/>
<add verb="*" path="LanapCaptcha.axd"
type="Lanap.BotDetect.CaptchaHandler, Lanap.BotDetect" />
<add verb="*" path="*.asmx" validate="false"
type="System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<add verb="*" path="*_AppService.axd" validate="false"
type="System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<add verb="GET,HEAD" path="ScriptResource.axd"
type="System.Web.Handlers.ScriptResourceHandler,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" validate="false"/>
<add verb="*" path="*.mvc" validate="false"
type="System.Web.Mvc.MvcHttpHandler, System.Web.Mvc,
Version=1.0.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
</httpHandlers>
<httpModules>
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<add name="UrlRoutingModule" type="System.Web.Routing.
UrlRoutingModule, System.Web.Routing, Version=3.5.0.0,
Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</httpModules>
</system.web>
<system.codedom>
<compilers>
<compiler language="VB.NET;cs;VBNet" extension=".cs"
warningLevel="4" type="Microsoft.VBNet.VBNetCodeProvider,
System, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089">
<providerOption name="CompilerVersion" value="v3.5"/>
<providerOption name="WarnAsError" value="false"/>
</compiler>
<compiler language="vb;vbs;visualbasic;vbscript"
extension=".vb" warningLevel="4" type="Microsoft.VisualBasic.
VBCodeProvider, System, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089">
<providerOption name="CompilerVersion" value="v3.5"/>
<providerOption name="OptionInfer" value="true"/>
<providerOption name="WarnAsError" value="false"/>
</compiler>
</compilers>
</system.codedom>
<system.web.extensions/>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true">
<remove name="ScriptModule" />
<remove name="UrlRoutingModule" />
<add name="ScriptModule" preCondition="managedHandler"
type="System.Web.Handlers.ScriptModule, System.Web.Extensions,
Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<add name="UrlRoutingModule" type="System.Web.Routing.
UrlRoutingModule, System.Web.Routing, Version=3.5.0.0,
Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</modules>
<handlers>
<remove name="WebServiceHandlerFactory-Integrated"/>
<remove name="ScriptHandlerFactory" />
<remove name="ScriptHandlerFactoryAppServices" />
<remove name="ScriptResource" />
<remove name="MvcHttpHandler" />
<remove name="UrlRoutingHandler" />
<remove name="LanapCaptchaHandler" />
<add name="ScriptHandlerFactory" verb="*" path="*.asmx"
preCondition="integratedMode" type="System.Web.Script.
Services.ScriptHandlerFactory, System.Web.Extensions,
Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<add name="ScriptHandlerFactoryAppServices" verb="*"
path="*_AppService.axd" preCondition="integratedMode"
type="System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<add name="ScriptResource" preCondition="integratedMode"
verb="GET,HEAD" path="ScriptResource.axd"
type="System.Web.Handlers.ScriptResourceHandler,
System.Web.Extensions, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35" />
<add name="MvcHttpHandler" preCondition="integratedMode"
verb="*" path="*.mvc" type="System.Web.Mvc.MvcHttpHandler,
System.Web.Mvc, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<add name="UrlRoutingHandler" preCondition="integratedMode"
verb="*" path="UrlRouting.axd" type="System.Web.
HttpForbiddenHandler, System.Web, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<add name="LanapCaptchaHandler" verb="*"
path="LanapCaptcha.axd" type="Lanap.BotDetect.CaptchaHandler,
Lanap.BotDetect" />
</handlers>
</system.webServer>
</configuration>
Explicación
El primer elemento que hay que añadir a Web.config file is the LBD_RequestPath está dentro de la declaración de <appSettings>. Esto es para configurar la ruta de BotDetect CAPTCHA con el fin de utilizar la extensión .axd extension, como sucede por defecto, con la extensión .aspx, debemos redirigir las consultas al código de ASP.NET MVC.
El siguiente cambio ocurre en la sección <sessionState>, en donde registramos un sessionIDManager personalizado, para asegurar que el audio del CAPTCHA funcione para navegadores Google Chrome y IE 7.0 + sobre Vista.
La sección <customErrors> es simplemente usada para mostrar posibles errores con rutas y situaciones comunes mostradas en la ayuda de ASP.NET MVC, considereando que no tener ASP.NET MVC instalado es el error más ocurrido que puede hacer fallar el proyecto de ejemplo actual. Si tiene ASP.NET MVC actualmente en su sistema y es de igual forma redirigido a la página Error.html, por favor descomente la línea de <customErrors> para saber con exactitud el error ocurrido.
Finalmente, registraremos un HttpHandler que BotDetect utiliza para funciones de imagen y audio dentro de <httpHandlers> y en las secciones <system.webServer>/<handlers> (así nos aseguramos que el CAPTCHA funcione correctamente dentro de IIS 7.0 y versiones más nuevas). Hemos modificado el manejo de la extensión .axd para motivos del funcionamiento de este ejemplo, como explicamos anteriormente.
Versiones Actuales de BotDetect
- BotDetect ASP.NET CAPTCHA v2.0.152009–11–23
- BotDetect ASP CAPTCHA v2.0.92009–02–12
Advertencia
Esta página es una traducción no oficial de la página original: BotDetect ASP.NET MVC CAPTCHA VB.NET Sample Project y puede estar incompleta, incorrecta o poco actualizada.
Última traducción del 2009-12-18. Esto se aplica para los productos BotDetect ASP.NET CAPTCHA v2.0.15 y BotDetect ASP CAPTCHA v2.0.9.





