BITácora de Software: c#

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.

 

Mostrando entradas con la etiqueta c#. Mostrar todas las entradas
Mostrando entradas con la etiqueta c#. Mostrar todas las entradas

sábado, 21 de enero de 2023

Creando proyecto desde la consola usando el CLI de .NET

enero 21, 2023 0
Creando proyecto desde la consola usando el CLI de .NET

 Hace tiempo que no publico entradas en este blog, así que decidi escribir esta pequeña entrada dónde dejo un pequeño ejemplo de cómo usar el CLI de .NET para agilizar la creación de nuestra solución, las capas y añadir las referencias.

Para quién no sepa, a partir de .NET 5 se "unificó" las tecnologias .net core y .net framework, es decir solo existe el .NET estandar. 

La interfaz de línea de comandos (CLI) de .NET viene dentro del SDK de .NET, actualmente esta herramienta es multiplataforma lo que nos facilita ejecutar los comandos sin ningún problema en windows o linux.

Por cuestión de facilidad el proyecto a crear tendrá el clásico y aburrido N-capas, usando como ejemplo el artículo  Sistema Gestión de Citas Parte 3: Creando el Proyecto en Visual Studio, la única diferencia será que la capa de presentación será una ASP.NET Core Web API (plantilla webapi) y no un  ASP.NET Core Web App (plantilla mvc).

Imagen 1: Arquitectura N Capas. (Fuente propia)



Lo que realiza cada comando es:

  • La línea 1 crea el proyecto "GestionCitas", se le especifica la salida usando el parametro "--ouput" para que la carpeta a crear sea "GestionCitas" y donde se crea el archivo .sln.
  • La línea 2 crea un proyecto Web API con el nombre "GestionCitas.API", en lenguaje seleccionado es C# y el target de .net es la versión 6, como hemos creado la solución y el directorio "GestionCitas" tenemos que especificar que el proyecto debe estar dentro de dicha ruta por lo que tenemos que usar el comando "--ouput" y espeficicarlo.
  • Las líneas 3,4 y 5 crea los proyectos del tipo librería de clases para las capas de datos, logica y entidades.
  • Las líneas 6,7 y 8 añade los proyectos creados a la solución.
  • Las líneas 10 a 14, añaden la referencia entre capas.
Imagen 2: Ejecución de comandos dotnet. (Fuente propia)


El resultado a nivel de directorio es:

Imagen 3: directorios creados con los comandos. (Fuente propia)

y así se ve en el visual studio:

Imagen 4: La solución vista desde el visual studio 2022. (Fuente propia)

Fuentes:

.NET CLI | Microsoft Learn, recuperado de https://learn.microsoft.com/en-us/dotnet/core/tools/
dotnet sln command - .NET CLI | Microsoft Learn, recuperado de https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-sln
dotnet new <TEMPLATE> - .NET CLI | Microsoft Learn, recuperado de https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-new
dotnet add reference command - .NET CLI | Microsoft Learn, recuperado de https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-add-reference
C# - .NET reunificado: planes de Microsoft para .NET 5 | Microsoft Learn, recuperado de https://learn.microsoft.com/es-es/archive/msdn-magazine/2019/july/csharp-net-reunified-microsoft%E2%80%99s-plans-for-net-5


domingo, 28 de abril de 2019

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

abril 28, 2019 0
[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]

miércoles, 23 de enero de 2019

Obtener Grupos de Red de Usuario de Active Directory [C#]

enero 23, 2019 0
Obtener Grupos de Red de Usuario de Active Directory [C#]
Para obtener los grupos de red a los que pertenece un usuario de active directory, debemos hacer uso del namespace System.DirectoryServices, esto con el fin de usar los objetos DirectoryEntry y DirectorySearch, de esta manera podremos acceder a la propiedad memberOf.

Imagen 1: Agregar referencia. (fuente propia)

Imagen 2: Agregar referencia de System.DirectoryServices. (fuente propia)

Empezamos armando una interfaz simple en la cuál tenemos que ingresar la ruta del active directory, el dominio al que pertenece el usuario, el usuario de active directory y su clave; estos datos son necesarios para poder realizar busquedas dentro del Active Directory.

Imagen 3: Interfaz de Usuario.

Primero tenemos que obtener el cn asignado al usuario de AD, la función Validar permite obtener ese dato, para ello inicializamos un objeto DirectoryEntry y le pasamos la ruta del AD, el dominio, el usuario (dominio y usuario se concatenan con un "\" en el centro) y la clave del usuario. Luego procedemos a realizar el filtro del SAMAccountName para obtener el CN (Nombre Común), dicha propiedad contiene en el indice 0 el dato que necesitamos :). Finalmente guardamos el valor obtenido en un string global (línea 15) ya que haremos uso de dicho valor en la función ListarGruposRed

Una vez obtenido el nombre del usuario, se procede a realizar la búsqueda de los grupos de red del usuario, para ello usamos el filtro CN, como dicho valor ya lo tenemos en la variable global datosUsuario concatenamos la variable que contiene la información, luego procedemos a cargar la propiedad "memberOf", esta propiedad retorna una colección con información de los grupos de red del usuario que enviamos su CN, a continuaciòn procedemos a contar sus elementos y por cada elemento de la colección extraemos el nombre del grupo de red, a priori sabemos que dicho dato se encuentra entre el primer igual (=) y la primera coma (,) por lo tanto obtenemos el indice de dichos simbolos y usando la función substring extraemos el nombre del grupo de red y finalmente procedemos a agregar dicho valor a nuestra lista.

Imagen 4: contenido de variable grupo. 

Imagen 5: Extraendo nombre de grupo de red. 

Imagen 6: obteniendo información de los grupos de red del usuario de activa directory.



Código completo: