lunes, 14 de octubre de 2019

MVC (Modelo Vista Controlador) con ASP.NET y VB.NET. Formateo y validación de los datos del Modelo usando Data Annotations

Sígamos con el ejemplo de la vez pasada. Ya hemos visto como usar el MVC con una base de datos MariaDB. Ahora veamos como podemos darle formato a dichos datos para su presentación, esto es particularmente útil en caso de tener datos numéricos o fechas.

Para hacer el ejemplo, agregue dos campos a mi tabla Libro: FechaPublicacion y Precio. Y por supuesto los incluiré en mi clase Libro dentro de mi modelo. 

Pero hablando de términos numéricos ¿que pasaría si quiero que me salga el número a dos decimales? Y en cuando a la Fecha ¿como puedo presentarla en cierto formato? Para esto existen los DataAnnotations, que son indicadores que sirvan para dar formato a las propiedades de nuestro modelo (para presentar los datos al usuario), como también para indicar ciertas validaciones sobre los datos.

Para poder usar esta característica, en la clase Libro debemos incluir el siguiente Import:

Imports System.ComponentModel.DataAnnotations

Veamos ahora como queda nuestra clase Libro:


En este caso hago varias cosas con las Data Annotations. Para la propiedad título la estoy marcando como obligatoria. Además de que no debe exceder los 100 caracteres de longitud.

Para el campo TipoLibro, así como FechaPublicación, establezco un nombre que será el que el usuario visualice en mi aplicación. 

Además establezco que FechaPublicacion es una fecha, y le doy un cierto formato, le indico que el formato se aplica también en modo de edición. Y lo mismo para Precio, le doy un formato al número a dos decimales.

Lo increíble de estas anotaciones es que Visual Studio las recuerda y aplica en cada momento y cada pantalla en mi aplicación. Me ahorra mucho código de validación e incluso de presentación, yo no tengo que preocuparme por dar formato a los datos en cada pantalla, Visual Studio se encarga.

Claro como agregue campos nuevos, tengo que volver a generar todas las vistas de mi aplicación, pero recordemos que este código lo puede generar Visual Studio. Mostraré solamente como queda la vista Index, que es la principal:

Vemos como se han agregado los nuevos campos.

Algo más que debo cambiar son mis controladores de Crear y Editar, pues el constructor de Libro ahora recibe más campos. Y sobre todo el Modelo de Biblioteca, pues debo manejar los nuevos campos.

Veamos como queda la función para leer los Libros de la Base de Datos:


Como vemos solo modifique el query y los datos que paso al constructor de Libro.

Veamos ahora los métodos para agregar y actualizar un libro:

 Public Sub AgregarLibro(ByVal nuevoLibro As Libro)
        Dim strSQL As String
strSQL = String.Format("INSERT INTO Libro(Isbn,Titulo,TipoLibro,FechaPublicacion,Precio)values('{0}','{1}','{2}','{3}',{4})", nuevoLibro.Isbn, nuevoLibro.Titulo, nuevoLibro.TipoLibro, nuevoLibro.FechaPublicacion.ToString("yyyy-MM-dd"), nuevoLibro.Precio)
        EjecutarSQLNoQuery(strSQL)
 End Sub

    Public Sub ActualizaLibro(ByVal nuevoLibro As Libro)
        Dim strSQL As String
        strSQL = String.Format("Update Libro set Titulo = '{0}', TipoLibro ='{1}', FechaPublicacion = '{2}', Precio = {3} WHERE Isbn='{4}'", nuevoLibro.Titulo, nuevoLibro.TipoLibro, nuevoLibro.FechaPublicacion.ToString("yyyy-MM-dd"), nuevoLibro.Precio, nuevoLibro.Isbn)
        EjecutarSQLNoQuery(strSQL)
    End Sub

Como vemos solamente se agregan los nuevos campos, respetando el formato que necesita MySQL para los datos.

El resultado de todo esto, es que podemos ver los datos con el formato correcto, en todas las pantallas:


Ahora una pantalla para agregar nuevo Libro, donde podemos notar el uso del calendario para la fechas:

Finalmente, la validación de los datos:





MVC (Modelo Vista Controlador) con ASP.NET y VB.NET usando una Base de Datos MariaDB

En la entrada pasada, hicé un ejemplo de MVC con ASP.NET y VB.NET. Dicho ejemplo uso objetos residentes en memoria para simular la persistencia de datos.

En esta ocasión modificaré dicho ejemplo para su uso con una Base de Datos. De esta manera tendremos persistencia de datos real. Y para que sea más ilustrativo usare MariaDB. No usaremos SQL-SERVER ya que en general es un ejemplo orientado a web.

Primero que nada, empezaremos modificando el Modelo. En realidad no modificaremos muchas cosas, pero queremos que los controladores de Alta, Edición e Index funcionen sobre la Base de Datos. De momento no modificaré el controlador de la acción Details, seguiremos usando objetos en memoria para esto. Asumimos que cada qué cargo el index traigo los datos de la Base de Datos, y después puedo visualizarlos y navegar por ellos usando los objetos que tengo en memoria.

Primero que nada modifiquemos el controlador, y el modelo para realizar la acción Index. Como voy a usar MySql debo agregar la referencia correspondiente. Y en mi clase Biblioteca, pondré el siguiente Import al inicio:

Imports MySql.Data.MySqlClient

Esto para trabajar sobre mi Base de Datos MySql. Pero veamos primero el controlador. Vamos a cambiar el del Index, en realidad el cambio es sencillo:



Simplemente ahora llamo a la función ObtenerLibros, la cual programará para que me regrese la Lista de Libros. En realidad el cambio más grande es en la parte del Modelo. Veamos la función que nos permite obtener los datos desde mi Base de Datos:


En la función Obtener Libros, simplemente incializo mi Lista de Libros con el valor que obtengo de la Base de Datos y la retorno al controlador. Como estoy usando los mismos objetos, no necesito modificar en lo absoluto las vistas.

Podemos notar en la función leerLibrosBD que uso mis objetos para conectarme a la BD, y ejecutar comandos SQL de manera normal, como siempre lo he hecho. Al final las clases del Modelo-Vista-Controlador, son solo eso, clases normales. En un DataSet usando un MySqlDataAdapter, guardó el resultado de mi comando SQL. Recorro el DataSet y en cada iteración creo un objeto Libro usando los datos que he traído de la Base de Datos. Luego agrego el libro a mi Lista. 

Esta Lista la uso solo en este método para guardar todos los libros traídos de la Base de Datos, ya que en la función ObtenerLibros es donde guardo realmente los valores en mi Lista que es propiedad de este objeto. Este paso es importante, ya que para la acción Details o Edit, operaré directamente sobre la Lista que tengo en memoria. Para que sea persistente, debemos hacer algo adicional en controlador Edit.

Veamos cómo funcionará dicho controlador, como mencionamos que aún usamos nuestra Lista de Libros residente en memoria, no es necesario modificar el controlador que genera la Vista. Pero si el que hace la acción de Editar, queremos que al Editar se guarde en la Base de Datos:


Ahora ejecutamos un método de la clase Biblioteca llamado ActualizaLibro. Que recibe los datos d nuestro Libro.

Como siempre el trabajo se hace en el Modelo. Pero antes de revisar nuestro modelo, veamos el controlador para agregar un Nuevo Libro. Funcionará de una manera muy similar:


Como vemos es muy similar. Usaré un método llamado AgregarLibro, al que le mandaré un objeto Libro para que haga el trabajo.

Veamos como el Modelo realiza estas dos acciones sobre la Base de Datos:


Las dos rutinas, AgregarLibro y ActualizaLibro hacen algo similar. En ambas preparó el SQL que usaré como comando. En el caso de AgregarLibro es un Insert y en ActualizaLibro  es un Update. Se preparan en base a los datos que recibo del controlador.

Luego tengo una subrutina EjecutarSQLNoQuery, básicamente la uso para ejecutar cualquier SQL que no retorne datos, esto incluye el Insert y el Update. Como vemos estas operaciones sobre la Base de Datos se hacen igual que siempre.

Como mis controladores siempre llaman a Index tras cada operación, los datos se refrescan de manera que el usuario ve en tiempo real el estado de los Datos en la Base de Datos.

La función obtenConexion no la subiré en este ejemplo, funciona igual que siempre, así que puedes realizarla por ti mismo con facilidad.

viernes, 11 de octubre de 2019

MVC (Modelo Vista Controlador). Un ejemplo con VB.NET y ASP.NET

El día de hoy realizaré un ejemplo usando el Modelo Vista Controlador. Este es un modelo o patrón de diseño de aplicaciones, que divide la arquitectura de una aplicación en 3 componentes: los datos (Modelo), la lógica de negocio (Controlador) y la interfaz de usuario (Vista). Explicándolo mas a detalle:

Modelo: Son los datos de nuestra aplicación.Esta capa tiene mecanismos para acceder a la información y también para actualizar su estado. Comúnmente se encarga de comunicarse con la  base de datos mediante funciones que accederán a las tablas y realizarán las funciones habituales de datos. 

Vista: Se trata del código que nos permitirá presentar los datos que el modelo nos proporciona,para que el usuario pueda visualizarlos.Como ejemplo podríamos decir que en una aplicación web es el código HTML y CSS que definen como se ven los datos.

Controlador: Es la capa que sirve de enlace entre la vista y el modelo. Representa los componentes que se encargan de la interacción del usuario, actuando de intermediario entre el usuario, el modelo y la vista. El controlador recoge las peticiones del usuario, interacciona con el modelo y finalmente selecciona que vista es la adecuada para mostrar los datos en cuestión. Podríamos decir que en desarrollo web implicaría uso de Javascript y scripts del lado del servidor.



Ahora bien este modelo o patrón pude aplicarse al desarrollo web o a cualquier ámbito. En este ejemplo, se usará con ASP.NET para desarrollo web.

ASP.NET ya tiene una serie de plantillas que nos facilitan mucho el desarrollo. Así que es fácil crear aplicaciones MVC si sabes como hacerlo.

El siguiente ejemplo fue tomado de este enlace. Si quieres aprender a usar MVC es un sitio muy completo. Sobre todo manejando C# por que es el lenguaje usado en los ejemplos. Además claro tienes que completar los ejemplos, no viene el código completo. Tomé el ejemplo, y lo hice para lenguaje VB.NET.

Empecemos por lo primero. Visual Studio ya tiene precargado todo lo que necesitas para hacer una aplicación MVC. Así que lo primero es crear un proyecto de tipo MVC.

Una vez creado tendremos una serie de carpetas. Una de ellas se llama Models. En esa carpeta da click secundario y dale Agregar->Clase

En este ejercicio el Modelo estará compuesto por clases, recuerda que el Modelo son nuestros datos. Usaremos dos clase, la clase Libro y la clase Biblioteca:

Esta clase es el core de la aplicación. Tiene 3 propiedades: Isbn, Titulo y TipoLibro. Todas son strings. Además cuenta con un constructor que recibe 3 parámetros y setea las 3 propiedades de esta clase (nota el uso de Me, donde indicamos que nos referimos a la instancia actual).

Ahora nuestra clase Biblioteca, que solo es una lista de Libros con algunos métodos para manipularlos:


Como vemos esta clase también tiene un constructor. De esta manera cuando se crea, podemos tener algunos libros para visualizar.

Hay una función que me permite regresar el número de libros, contando los elementos de mi lista de libros. Además hay otra función que me regresa el libro de acuerdo al Isbn, que uso como llave de búsqueda.

Con esto tenemos listo el modelo. El siguiente paso es el controlador. Para eso en la carpeta Controllers damos click secundario y escogemos Agregar->Controlador . Escogemos el "Controlador MVC con acciones de lectura y escritura", y le nombramos BibliotecaController.

El controlador contiene algunas acciones que podemos realizar sobre nuestro Modelo, Editar, Crear, Borrar o Ver Detalles. Tiene una acción Index, que es la que nos visualiza la página principal. Así que será la primera que programaremos.

Pero antes, instaciaremos una Biblioteca, para tener datos con los que trabajar:

Shared miBiblioteca As Biblioteca = New Biblioteca()

Es importante notar que la Biblioteca de definió como Shared. De esta manera su valor es dependiente de la clase y compartido entre instancias. Esto es necesario por que Controller se actualiza constantemente , si uso objetos normales perdería los valores y no tendría un almacenaje permanente. Pero al ser shared, me funciona igual que el static de C#, no importa si instancio o no objetos, el valor permanece.

Ahora veamos como implementar la función Index:

¿Sencillo no? El controlador solo regresa una lista de libros de Biblioteca. Aquí el trabajo lo hace la vista. Debo presentar esa lista de una forma legible en HTML. Para generarla Visual Studio me da facilidades. Solo debo hacer click secundario en mi función y dar click en Agregar Vista.

Visual Studio tiene una serie de plantillas que nos ayudan a generar las vistas. Y es que en realidad aquí es donde va la mayor parte del código y del trabajo (esto es programación web, se requiere mucho tiempo en programar la interfaz, no es como en windows form que es arrastrar y sotar).

Una vez que le damos Agregar Vista parece un Cuadro de Dialogo. Elijamos la Plantilla List, que nos permite visualizar una lista de elementos. En Clase de Modelo, elegimos Libro( recuerda veremos una lista de libros, no de Bibliotecas). Y listo ya tenemos nuestra maravillosa lista...que no es otra cosa que una tabla:


Aquí podemos notar que model, contiene los datos de nuestro modelo. En los encabezados usamos  Html.DisplayNameFor que nos permite desplegar el nombre de la propiedad. Esto se hace sobre el modelo.

Con un ciclo recorremos los items del modelo, y en cada renglón de la tabla ponemos los datos con Html.DisplayFor tomándolos de cada item.

Adicionalmente puse los actionLink para que ejecuten las acciones de Editar, Ver Detalles o Borrar. Cuando eso sucede envío el id que en este caso es el Isbn.

Es importante notar que Visual Studio no genera este código tal cual, solo genera el cascarón con varias cosas predeterminadas, pero hay que retocarlo.

Programemos ahora la acción Create que agrega un nuevo Libro:


En este tipo de acciones tenemos dos funciones: la primera nos genera la vista de la pantalla que usamos para interactuar con el usuario, y la segunda es la que hace en si hace la acción de crear, en base a a la collection que se nos retorna vía POST de esa pantalla. En esta segunda función, simplemente ejecuto un Add sobre miBiblioteca, con los parámetros que me envío dicha collection. Y redirecciono a mi pagina index.

Solo para la primera función necesitare un vista, que creo de manera similar a la del index. Elegiré la plantilla Create y la Clase de Modelo Libro.


Este código crea una forma que contiene etiquetas y cuadros de texto para rellenar de acuerdo a las propiedades del Libro. Es interesante notar que en mi controlador, obvie el campo Isbn, no lo insertó con el valor que trae de la forma, si no que es autogenerado con  código.

En este caso Visual Studio para la vista si nos genera todo el código que necesitamos. Incluye el botón que envía los datos.

Ahora veamos el controlador y vista para Ver Detalles del Libro:

Como vemos el controlador es sencillo, solamente se ejecuta el método ObtenerPorIsbn que hace una búsqueda del libro, y me lo regresa si concuerda el Isbn.

De la misma como con los anteriores generaremos la vista dando click secundario. Para la Plantilla elegimos Details, y Clase Modelo, Libro.

Nos genera la siguiente Vista:

Algo que debemos notar, es que en mi controlador id originalmente era Integer. Modifiqué el código por que uso como llave el Isbn que es un String al hacer la búsqueda.

La Vista es solamente una representación de los datos de dicho elemento que he encontrado pero de una forma diferente. Por su puesto podríamos elegir en la vista Index mostrar solo ciertos datos, y que en el detalle se muestre el objeto completo.

Con esto en mente hagamos la parte de la Edición. Primero el controlador, al igual que cuando creamos un nuevo modelo, este tiene dos funciones, una donde mandamos la vista de la pantalla de edición y otra donde realmente hacemos la edición del elemento:


Como puedes ver es sencillo. Para generar la vista, primero obtengo el libro que deseo modificar. Recuerda que a estos métodos se accede pulsando el action Link del index, así que me envía el Isbn como id (la plantilla lo tenía como integer pero lo modifiqué a String).  Una vez que encuentro mi libro, se generará la Vista.

La función de Edición que se ejecuta tras recibir vía POST los datos de edición, simplemente recorre mi lista de libros y cuando encuentra que el Isbn= id, entonces actualiza los datos que yo desee, tomándolos de la collection que recibi.

Finalmente la vista, que seguro ya conoces como generarla, quedaría así:


Simplemente es una pantalla de edición, muy parecida a la de crear nuevo Libro, pero que cargará los datos del Libro que seleccionaste.

Y así finalizamos. Queda pendiente el Delete, ese lo dejo como ejercicio.

Shared en VB.NET y su relación con static C#

Quizá en ocasiones te has encontrado con la palabra reservada Shared en VB.NET y te has preguntado que significa.

En pocas palabras , para los que vienen de C#, un método, objeto o propiedad shared es equivalente al declarado como static.

Bueno, básicamente son iguales , pero con pequeñas diferencias. Ambos son identificadores que ligan el método, propiedad u objeto a la clase, no a las instancias de la misma.

En VB.NET Shared significa como su nombre lo especifica: compartido. En otras palabras ese método, propiedad u objeto, esta ligado a la clase y se comparte además entre las instancias de la misma, siendo único para todos. En cambio las propiedades, métodos y objetos normales, son únicos para cada instancia de la clase u objeto.

Por lo tanto no es necesario ni siquiera que exista una instancia de determinada clase, el método o propiedad shared puede accederse desde que comienza la vida de la clase, usualmente al iniciar el programa. Y cuando accedemos a él, por ejemplo tratándose de una propiedad, no modificamos su valor en una determinada instancia, si no de manera general en toda clase. Por lo tanto puede decirse que ese valor es compartido entre todas las instancias de la misma.

En este sentido es exactamente igual que lo que definimos con static en C# y para efectos prácticos se comportan igual. Una sutil diferencia: para acceder cualquier static en C#, debemos usar la definición de la clase , no una instancia; pero como en VB.NET dichos elementos son compartidos, podemos accederlos desde una instancia o desde la clase. En cambio en C# el static, esta ligado a la definición de la clase.

Veamos un ejemplo, tanto en C# como en VB.NET

public class Employee
{
    public string id;
    public string name;
  public static int employeeCounter;

    public static int AddEmployee()
    {
        return ++employeeCounter;
    }
}


Vemos que en C# cuento con una propiedad estática y un método estático, estos pertenecen a la clase ,no a sus instancias. Para accederlos lo hago directamente desde la clase. Un efecto de esto es que dentro de mi método static no puedo referenciar con this (esta palabra reservada se refiere a la instancia actual de la clase) a las propiedades normales del objeto, ya que puede ser que no existan y son independientes entre objetos, y él método static no lo es. Y las propiedades static tampoco pueden ser accedidas para this.

En este caso se implemento un contador de empleados que puedo usar para guardar el total de empleados que tengo. Esto funciona por que employeeCounter se crea con la clase, no necesita de ninguna instancia u objeto para existir. Y su valor no cambia, ni se vuelve a crear cuando instancio un objeto de dicha clase. Si employeeCounter no fuera static, su valor se reseatería cada vez que creo un nuevo objeto, por que dependería de la instancia de dicho objeto , no de la clase. Si destruyo el objeto, se perdería el valor. Pero como es static me sirve como contenedor globlal.

Y puedo llamarlo así en mi clase Main:

 Employee1 e = new Employee();
 Employee.AddEmployee();
 Employee2 e = new Employee();
 Employee.AddEmployee();
 Console.Write($"Número de Empleados: {Employee.employeeCounter}");

El resultado al imprimir será de 2, en cambio si employeeCounter no fuera static, para cada instancia de la clase tendría un valor diferente.

Veamos ahora el mismo ejemplo en VB.NET:

Public Class Empleado
    Public id As String
    Public nombre As String
    Public Shared contadorEmpleado As Integer

    Public Shared Function agregaEmpleado() As Integer
        contadorEmpleado = contadorEmpleado + 1
        Return contadorEmpleado
    End Function
End Class

Como vemos es similar, solo que uso la palabra Shared. Opera en un método compartido sobre una propiedad compartida. Cuando desee operar en un método compartido, al igual que un static de C#, debo hacerlo sobre propiedades que sean shared de la misma clase, o que sean propias del método o recibidas por parámetro. No puedo operar sobre ninguna propiedad de la clase que no sea shared, por que puede ser que no existan aún, además su ámbito es dependiente de la instancia.  Es decir no puedo hacer nada sobre las propiedades id y nombre, por que quizá no existen aún, además son independientes para cada objeto, no puedo manipularlas desde un método compartido. 

Si quisiera usar id y nombre, primero debería crear un objeto de esta clase, que además solo serviría para usarse en este método, claro que podría retornarlo desde el método como resultado. Pero dado que la invocación a shared es compartida, es imposible que haga referencia a las propiedades particulares de la instancia.....o incluso a métodos que no sean shared; lo mismo pasaría con static de C#, solo pueden usar o llamar propiedades y métodos static. Así que igual como en C# no podemos usar this, en VB.NET no podemos usar el equivalente Me que hace referencia a la instancia actual.

Veamos ahora como uso esta clase:

 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim empleado1 As New Empleado
        Empleado.agregaEmpleado()
        Dim empleado2 As New Empleado
        empleado2.agregaEmpleado()
        MsgBox(empleado2.contadorEmpleado)
 End Sub

Vemos que es idéntico a C#, puedo usar el método agregaEmpleado directamente desde la clase, y podría hacerlo sin necesidad de crear ninguna instancia. Pero hay una pequeña diferencia ¿verdad?.En VB.NET si puedo acceder a shared desde una instancia. Al final el resultado es igual a si lo hiciera desde la clase ya que shared indica que el valor de contadorEmpleado es compartido por todas las instancias de Empleado.





miércoles, 9 de octubre de 2019

Formulario registro con ASP.NET y VB.NET. Uso de Base de Datos MariaDB. Leer parametros de conexión de archivo de texto. Uso de un stored procedure para insertar registros. Uso de encriptación MD5

El día de hoy voy a implementar un ejercicio más complejo en ASP.NET , elaboraré un formulario de registro de usuarios. Los datos del formulario se insertarán en una Base de Datos, pero para hacerlo más de acuerdo a un desarrollo web, utilizaré la Base de Datos MariaDB, no el tradicional SQL-SERVER.

Para esto lo primero que debo hacer es agregar la referencia a la librería MySql.Data que encontraremos en la sección Ensamblados->Extensiones , de las referencias.

Primero veamos los elementos de la interfaz web en ASP.NET


Para variar he incluido varios controles, cajas de texto, radio buttons, un control Calendar para la fecha de Nacimiento e incluso un DropDownList, el equivalente a un comboBox, para que de la lista desplegable el usuario elija el país de origen.


También agregué un checkbox para que el usuario confirme si acepta los términos y condiciones, y un botón que usaré para guardar los datos.

Además de una etiqueta informativa que llenaré con mensajes de validación de datos, así como de éxito en caso de insertar el registro.

Como vemos lo primero que necesito en mi código de VB es poblar el DropDownList de países, lo cual voy  a hacer tomando los datos desde mi Base de Datos. Para el manejo de la Base de Datos creo una clase llamada usuarioDAO que estará manejando el acceso a la misma. 

Así que al cargar mi página debo acceder a la Base de Datos y poblar mi lista desplegable, lo que lograre con el siguiente código:

Como usaré varios objetos propios de la librería de conexión a MySQL (MariaDB usa la misma librería), debo iniciar antes con un Imports MySql.Data.MySqlClient.

Como vemos una vez que obtengo la conexión uso un objeto MySqlCommand para ejecutar el comando necesario para leer los datos. El tipo de comando es Text que indica que es una consulta SQL. Le asignó la conexión a mi comando, además usaré un DataSet y un MySqlDataAdapter.

Luego le indico al DataAdapter que voy a usar un comando de tipo select, para de esta manera poder recuperar datos de la Base de Datos, y le asigno mi objeto MySqlCommand. Uso el método Fill para ejecutar mi comando y llenar mi DataSet.

Una vez llenado el DataSet, lo uso como fuente de datos de mi DropDownList al establecer la propiedad DataSource = ds.Tables(0). Después en la propiedad DataValueField le indicó cual de los campos usaré como valor, y en la propiedad DataTextField cual campo se desplegara como texto para que lo vea el usuario.

Finalmente debo ejecutar el método DataBind para poblar mi lista desplegable, y cierro la conexión a la Base de Datos.

La función para Obtener la conexión a la Base de Datos es la siguiente:

 Dim archivoConexion As String = "C:\Users\Franquicias\datosConexion.txt"
    Public Function obtenConexion() As MySqlConnection
        Dim datosConexion As Conexion
        Dim cadenaConexion As String
        datosConexion = Conexion.leeDatosConexion(archivoConexion)
   cadenaConexion = "Server=" + datosConexion.Servidor + ";Database=" + datosConexion.Database + ";User id=" + datosConexion.Usuario + ";Password=" + datosConexion.Password + ";Port=" + datosConexion.Puerto + ";"
        Dim conn As New MySqlConnection(cadenaConexion)
        conn.Open()
        Return conn
    End Function

Aquí simplemente un objeto MySqlConnection, al que debo pasar un cadena de conexión como string, la cual contiene el servidor, puerto, bd, usuario y contraseña. En mi caso leeré todos estos datos de un archivo de texto. Este se lo envío como parámetro a la función leeDatosConexión.

Esta es mi función para leer el archivo de texto:


Básicamente es la función para leer archivos de texto de siempre, en mi archivo guarde los datos de conexión con el formato clave,valor ; así que al leer una línea del archivo en un select case evaluó que dato tengo de acuerdo a la clave, y lo guardo en un objeto de tipo Conexion de acuerdo al campo elegido. Es importante notar que esta función es Shared, ya que la incluí dentro de mi clase Conexión pero deseo que este disponible aun sin instanciar esta clase, así de que al ponerla como shared se puede usar directamente desde la clase sin instanciar ningún objeto.

Una vez definido como conectarme a la Base de datos, veamos el código para guardar los datos:

Al momento de dar click en mi botón para guardar, primero hago una serie de validaciones que explicaré brevemente más adelante.

He creado un objeto Usuario, que contiene en sus propiedades todos los datos que deseo guardar, para usarlo como contenedor. La función colectaDatosUsuario simplemente toma los datos desde mis objetos del sistema y los guarda en el objeto usuario. Es importante respetar los tipos de dato, por ejemplo Telefono esta definido como Double y CodigoPostal como Integer, así que hago las respectivas conversiones. Sexo es un boolean que se puede asignar directamente de la propiedad Checked de un radio button, y FechaNacimiento es un Date, que igual puedo asignar desde el Calendar.SelectedDate

Algo más que es importante notar es que la contraseña va encriptada en MD5. Para hacer la encriptación usamos el siguiente código:


Esta función recibe nuestra contraseña como string, la convierte a binario, le aplica el hashing en MD5, y luego vuelve a convertir ese resultado en string.

Para poder hacer eso necesitamos importar la librería Imports System.Security.Cryptography.

Regresando al código original, después de obtener los datos llamo la función insertUsuario de mi objeto de acceso a datos. Más adelante explicaré su funcionamiento. Si todo sale bien pongo un mensaje de éxito, y cambio el color de mi etiqueta de mensajes (la tenía en rojo) al verde.

Veamos brevemente algunas validaciones:


Son validaciones sencillas del tipo validar que se haya ingresado un dato, validar que sea numero en algunos casos, la más complicada es validar Email donde se usan expresiones regulares para ver que sea el formato correcto.

Veamos ahora como inserto los datos en mi Base de Datos:


Una vez mas usamos un MySqlCommand, pero esta vez de tipo StoredProcedure. Cuando instanciamos el comando le decimos el nombre del stored procedure.

Luego agregamos los parámetros del stored procedure. Yo hice una función que facilita esta tarea, recibe el nombre del parámetro, el tipo de acuerdo a la enumeración MySqlDbType, y el valor. Cuando son VARCHAR es importante especificar la longitud.

Finalmente ejecuto mi stored procedure con el método ExecuteNonQuery. Y cierro la conexión.

Mi código de Base de Datos,  es un stored rocedure que recibirá la lista de parámetros y hará el insert a la tabla:


lunes, 7 de octubre de 2019

Radio Buttons ASP.NET, enlace a buscadores, con lectura de archivo de texto usando VB.NET

Hoy realicé otro pequeño ejercicio en ASP.NET. En esta ocasión se trata de leer de un archivo de texto el nombre de ciertos buscadores de Internet, para dinámicamente asignarlos a ciertos radio buttons que tendré en mi página web. Todo esto lo haré con VB.NET

El código que uso en VB.NET es exactamente el que uso en una aplicación de escritorio. Esa es una de las ventajas de ASP.NET, si ya conoces el lenguaje te facilita el desarrollo. 

Primero que nada analizemos el siguiente código:

Este código lo puse en el archivo Default.aspx.vb que es el archivo de código de mi página. Este archivo, que se llama igual que mi página pero con extensión .vb, en realidad es una clase que construye mi página usando Visual Basic. Por eso la primera línea es así.

Public Class _Default
    Inherits Page

Esto quiere decir que mi página hereda de la clase Page, la cual representa un archivo .aspx .

A continuación programe el método Page_Load, y en este es donde puedo construir y modificar los elementos de mi página, ya que se ejecuta al cargar mi página.

En este caso leo un archivo de texto, y en base a los datos que contiene pongo el texto a mis radio buttons, además de llenar un diccionario con esos datos que son el nombre del buscador y el enlace del mismo.

En este caso la función para leer el archivo de texto es el siguiente:


En este caso puedo notar como es idéntica a otras funciones que  he usado en otros ejemplos para leer archivos de texto. Básicamente usa los objetos y librerías del sistema de siempre que usas en Visual Basic. Es importante recordar que al inicio antes de tu  clase debes importar la librería System.IO para leer los archivos de texto.

Para el manejo de eventos en mi página programo el siguiente método:


Muy sencillo solo programamos la funcionalidad  igual que siempre en Visual Basic. Tengo un botón que al darle click evalúa cual de mis radio buttons esta activo, y toma el texto del mismo.

Luego uso el método TryGetValue de mi objeto diccionario, el cual me permite hacer una búsqueda en el diccionario y recuperar el valor contenido de acuerdo a una clave. De esta manera obtengo el enlace de acuerdo al nombre.

Uso ahora el método Response.Redirect para redirigir mi página al enlace solicitado.

Finalmente el código HTML de mi página:

Aquí lo más importante es poner el nombre del método en la propiedad onclick para que ejecute el método adecuado de nuestro código de Visual Basic en el botón que activa el enlace al buscador.

Además en los radio buttons, es importante la propiedad Group Name que es el grupo al que pertenecen los radio buttons. Con esta propiedad le indicamos a ASP que todos son del mismo grupo y por lo tanto actúan como radio buttons (cuando activo uno, desactivo los demás).


miércoles, 2 de octubre de 2019

Descomprimir archivos. Manipulación de archivos de Excel. Envío de archivos por Email de Gmail. Todo en VB.NET

Este ejemplo consta de lo siguiente, tengo una lista de archivos, los cuales deseo descomprimir, cambiar su nombre, luego en cada carpeta leer el archivo de Excel que viene dentro del .zip y formatearlo y finalmente mandar esa información por e-mail, usando mi cuenta de Gmail.

Para empezar estas son las librerías que usaré:

Imports System.IO
Imports Excel = Microsoft.Office.Interop.Excel
Imports System.Net.Mail
Imports System.Net.Mime

La primera para leer archivos de texto, la segunda para el uso de Excel, la tercera y cuarta para el uso del correo electrónico.

El código principal es el siguiente:


Aquí primero que nada leo mi lista de archivos. Luego la itero para trabajar sobre ellos.

Es importante notar la variable carpetaDestinoZIP que contiene la carpeta donde descomprimiré mis archivos .zip . La ruta contiene espacios en blanco, por lo que debo mandarla a WINRAR con comillas dobles al inicio y al final. Para eso, escapo las comillas con otra ". Además debe tener el carácter "\" al final.

De la misma manera en la variable archivoZIP tengo el nombre de mi archivo comprimido con ruta, e igual como contiene espacios en blanco debe ir con comillas.

Luego utilizo el objeto Process que me sirve para invocar otra aplicación desde VB.NET. Esta vez dejaré que el trabajo de descompresión lo haga la aplicación de WINRAR que tengo instalada en mi máquina. En este caso invoco WINRAR, mandandole como parámetro "x" que significa descomprimir, el nombre del archivo a descomprimir y la carpeta de destino. En este caso WINRAR crea la carpeta si no existe. Esto equivale a llamar a WINRAR desde la línea de comando. Aquí un manual para el uso de WINRAR como comando.

Después mando llamar a la subrutina procesaArchivo, que va a renombrar el archivo y darle formato.

Posteriormente, uso una lista para agrupar los archivos que enviare por correo, ya que debe ser de 2 en 2. La rutina correoArchivo recibe esa lista y manda el correo.

Ahora explicare las subrutinas y funciones:


Esta función simplemente lee un archivo de texto, en donde separados por comas tengo el nombre del archivo .zip, y el nombre que le pondré al archivo al descomprimirlo.

Ahora la parte de Excel:


Realmente lo que hago es solamente abrir el archivo de Excel, ejecutar una macro sobre el, y después guardarlo con el nuevo nombre que deseo que tenga.

Es importante notar que en el método SaveAs el segundo argumento es el tipo de archivo. En mi caso el archivo original es un ".csv" y deseo guardarlo como un libro de Excel estándar. Así que le corresponde el 56, que es el formato de Excel 97-2003 (.xls). Para la lista completa de opciones de tipo de archivo este enlace.

En la macro solo elimino algunos rangos de columnas, hago el tamaño de algunas autojustado al contenido, y borró la primera línea.

Veamos ahora la rutina del Email:


Primero con un ciclo recorro mi lista de archivos adjuntos. Uso el objeto tipo attachment para agregar nuevos adjuntos al correo. Para crear un adjunto solo debo indicar la ruta del archivo y el tipo, en este caso un octet (binario).

Uso un objeto System.Net.Mail.SmtpClient para enviar los archivos. Primero le doy las credenciales, es decir mi cuenta de correo y contraseña.

Luego indico el host, que es el de Gmail, el puerto y debo indicarle que la información va vía SSl, que es requerido por la seguridad de Gmail.

Uso un objeto System.Net.Mail.MailMessage para enviar mi correo. Con el método .[To].Add le agrego un destinatario , la dirección de correo a donde lo enviare.

Además agrego el Subjet, especifico la encodificación, agrego el Body con su encodificacion. La prioridad la definí como normal.

Finalmente, ejecuto el Send mandando como parámetro mi mensaje.

Es importante mencionar que para que Gmail no me rechace los correos, debo tener activada la opción Permitir el acceso de aplicaciones poco seguras en mi cuenta de correo.

MVC (Modelo Vista Controlador) con ASP.NET y VB.NET. Formateo y validación de los datos del Modelo usando Data Annotations

Sígamos con el ejemplo de la vez pasada. Ya hemos visto como usar el MVC con una base de datos MariaDB. Ahora veamos como podemos darle for...