[C#] Evitar doble submit (doble click) al pulsar botón en ASP.NET - BITácora de Software

Bitacora de software: Programación web, programación de escritorio, programación de servicios, configuración de servidores, IIS, lenguajes de programación C++, C#, PHP, trinity core, unity, jquery, arduino, etc.

 

domingo, 28 de abril de 2019

[C#] Evitar doble submit (doble click) al pulsar botón en ASP.NET

Supongamos que tenemos un portal web que permite registrar los datos de los asistentes a un evento X. ¿Qué pasaría si no validamos las peticiones repetidas que envía el usuario?, pues acabaríamos teniendo registros duplicados en la base de datos con diferencia de mili segundos. En la siguiente imagen podemos apreciar dicho escenario:

Imagen 1: registros duplicados con diferencia de milisegundos. (Fuente: propia)


El formulario que permite registrar en la BD es simple, cuenta con los campos nombres, apellidos y e-mail (el campo fecha_registro es un campo con valor por defecto getdate() que obtiene la fecha y hora actual cuando se crea el registro).

Imagen 2: Formulario de registro de asistentes. (Fuente: propia)

Para levantar el entorno de prueba, creamos la base de datos, la tabla y el procedimiento almacenado que nos permita registrar los datos:


El proyecto de visual Studio con el código defectuoso, lo puedes descargar del siguiente enlace:

[Descargar Código Fuente / Download Code Source]


En la capa de presentación abrimos el archivo RegistroDeAsistente.aspx.cs y nos vamos a centrar sobre la función click del botón registrar (línea 19 - 50):


La función es simple, primero verifica que los campos no se encuentren vacios, luego inicializa una variable que contendrá la información del asistente y se invoca la función registrarAsistente para hacer el registro en la base de datos. Finalmente la función de registro nos retorna un Id autogenerado por la base de datos, si el valor devuelto es mayor a 0 quiere decir que el registro fue exitoso entonces procedemos a limpiar los datos de los controles y mostrarmos un mensaje de confirmación para el usuario.

Imagen 3: Formulario de registro de asistente con datos. (Fuente: propia)

Imagen 4: Registros grabados con diferencia de milisegundos. (Fuente: propia)


Imagen 5: Mensaje "Registro correcto!". (Fuente: propia)


Parchando el doble submit

Para corregir el problema lo mas fácil sería bloquear/ocultar el botón mediante Javascript y volver activarlo cuando tengamos la respuesta, pero existe la posibilidad de que el usuario des-habilite Javascript en su navegador.

Para dar solución al problema usaremos 2 ViewState, una variable sesión y la función Page_PreRender. ¿cómo funciona la solución?, cuando cargamos la página esta invoca a la función Page_Load al ser la primera carga de la página ingresa a la línea 27, se captura la fecha y hora actual y se almacena en la variable sesión SolicitudRegistro, luego se invoca a la función Page_PreRender, dentro de esta función se asigna el valor de la sesión SolicitudRegistro al ViewState solicitudActual, es decir, ambas variables son identicas en valores (fecha y hora). Cuando se pulse sobre el botón Registrar se comparará la variables sesión y el viewstate, como ambas variables tienen el mismo valor la condición será verdadera e ingresará dentro del bloque if. La línea 37 modifica el valor de la variable sesión con una fecha y hora diferente a la inicial esto con el fin de que las variable sea diferente al valor del viewstate, con esta modificación en el código se logra que ya no se vuelva a ingresa al bloque de registro. Si se da el escenario donde el usuario pulse repetidamente sobre el botón registrar el código solo invocará una vez la función registrar y la respuesta se almacenará en el ViewState registroCorrecto que servirá como bandera para verificar el dato que se obtuvo, y poder realizar la acción de limpiar las cajas de texto y mostrar el mensaje de registro correcto.

El proyecto de visual Studio con el código solución, lo puedes descargar del siguiente enlace:

[Descargar Código Fuente / Download Code Source]

No hay comentarios:

Publicar un comentario