Etiqueta: Visual Basic

  • Ahora entiendo mejor porqué ya no quieren seguir actualizando/avanzando Visual Basic

    Pues eso… viendo las novedades de C# 10.0 me he topado con los detalles de la «novedad» Global using directives, dicho de esa forma parece algo «WOW!», y… es algo que siempre he querido que quitasen de forma predeterminada al crear un nuevo proyecto de Visual Basic para .NET: que haya importaciones implícitas de espacios de nombres al crear un nuevo proyecto.

    Y eso es lo que es esa «nueva» característica de C# 10.0, crear definiciones «using» (ya que «Imports» es cosa de Visual Basic para .NET) de los espacios de nombres más habituales según el tipo de proyecto creado.

    Que sí, que está muy bien, pero a mí nunca me ha gustado, de hecho, en la mayoría de los proyectos que creaba (sobre todo si era para compartirlo como parte de algún artículo), lo quitaba, con idea de así tener que escribir las importaciones de espacios de nombres en cada fichero (de código) de ese proyecto. Porque es la única forma de saber «a ciencia cierta» qué espacios de nombres se estaban usando en ese fichero de código.

    Para que nos entendamos, a diferencia de C#, en Visual Basic el espacio de nombres System.Text nunca se importa de forma predeterminada, algo que sí ocurre en los proyectos de C#; por tanto, si quiero crear un nuevo objeto del tipo StringBuilder, o bien lo creo usando el nombre «completo» de la clase StringBuilder: System.Text.StringBuilder o bien declaro la importación del espacio de nombres System.Text y ya el compilador sabrá que StringBuilder está accesible (al revisar las clases contenidas en cada uno de los espacios de nombres que estén incluidos en las importaciones).

    ¡Eh! que no es una crítica, que me parece muy bien, y si ahora los del TEAM de C# lo están añadiendo como algo «predeterminado» será porque tampoco será tan malo, lo único que digo es que sigue siendo lo mismo que teníamos los «desarrollado-res» de Visual Basic desde hace ya casi 20 años… ¡NOVEDAD! WOW! 😉

    Total, a lo que iba, que ya no hace falta seguir dando nuevas características a Visual Basic, porque al final C# será como era Visual Basic hace 20 años… eso sí, con (entre otras cosas) acabando la línea con un punto y coma.

    Pero preferiría que Visual Basic evolucionara con las «nuevas características» realmente nuevas, para que a los que no nos gusta usar punto y coma para indicar que una instrucción ha finalizado o poner cosas entre llaves, etc., etc., y dejar de ver cómo C# evoluciona para hacer cosas que desde «siempre» ha hecho Visual Basic y, casi seguro, que era criticado por eso… Y si no me crees, échale un vistazo a las declaraciones sin tipos de variables (que, siempre al estilo de C#) en C# también lo añadieron en su día como novedad novedosa…

    Nos vemos.
    Guillermo

  • Por fin se podrán ver los artículos / posts de elguillemola.com desde elguille.info

    Pues eso, que desde que cambié el alojamiento de «mi sitio», elguille.info, de Axarnet/Domitienda a acens (de telefónica) los enlaces que tenía «incrustados» en las páginas (para que mostrase en una página de mi sitio el artículo de mi blog (este) no se mostraban a causa de un error que mostraba este texto:
    The request was aborted: Could not create SSL/TLS secure channel
    La solución ha sido fácil (después de haber buscado en la red sobre este error) y que he he econtrado en StackOverflow, concretamente en un comentario a una de las respuestas, no puedo poner el enlace a ese comentario, pero es el que tiene este texto:
    You don’t need to exclusively set it to a single type, you can simply append as well. System.Net.ServicePointManager.SecurityProtocol |= System.Net.SecurityProtocolType.Tls12;
    – Nae Mar 20 ’18 at 8:44

    Ese código es para C#, en Visual Basic sería este:

    
    
    System.Net.ServicePointManager.SecurityProtocol = 
                System.Net.ServicePointManager.SecurityProtocol Or
                   System.Net.SecurityProtocolType.Tls12
    
    
    
    

    Lo que tengo que hacer ahora es ver si ese código simplemente lo puedo poner en la página maestra o tendré que ponerlo en cada página… creo que si se ejecuta una sola vez es suficiente, así que… si ves que da nuevamente ese error, te ruego que me lo digas. Gracias.

    Nos vemos.
    Guillermo

  • Obtener las IPs (IPv4 e IPv6) del usuario y mostrar solo las IPv4 usando .NET (Core) [Código para Visual Basic y C#]

    Pues eso… aquí tienes un ejemplo que son 2 (o cuatro si tenemos en cuenta que el código que te voy a mostrar es tanto para Visual Basic como para C#/CSharp) y es para obtener las IPs del usuario (o donde se ejecute el código) y de esas IPs (que contendrá las IPv6 y las IPv4) extraer solo las IPv4.

    Este código utiliza expresiones regulares (RegEx) y por tanto necesitas añadir una importación del espacio de nombres System.Text.RegularExpressions, también utiliza métodos para acceder al nombre del equipo (host name) y obtener las direcciones IP, por tanto, necesitarás una importación al espacio de nombres System.Net.

    Este código sirve tanto para aplicaciones de escritorio (los ejemplos están hechos para aplicaciones de consola para todas las plataformas), aplicaciones móviles y aplicaciones WEB.

    Yo lo he probado en las dos primeras, y cuando lo haga en la tercera, te mostraré el código usado (o lo pondré en el repositorio de GitHub que crearé para poner el código de ejemplo) y las cosas que debas tener en cuenta, siempre y cuando tengas algo que tener en cuenta 😉

    Nota 01-sep-2021:
    Ya he publicado una página ASPX (asp-net) para probar el código.
    Para esa página he creado una DLL con idea de ponerla en el directorio BIN del hosting donde tengo alojado «mi sitio» www.elguille.info.
    En GitHub también está el código de esa DLL (del proyecto, que en este caso lo he creado con VB).
    Este es el enlace de la página de prueba: ComoNET: Utils IP (.NET Core) (elguille.info)

    Nota:
    Las dos funciones principales: la que obtiene las IPs y la otra que extrae las IPv4 de esas IPs están en una clase estática (compartida sería en VB, pero en este caso no es necesario indicar Shared) con métodos estáticos (así debe ser en C#), esos métodos en Visual Basic están declarados con Shared, mientras que en C# se utiliza static.

    En realidad, en Visual Basic podría haber usado un módulo (Module) en vez de una clase y definir expresamente los métodos de forma compartida, pero la diferencia de declarar los métodos como compartidos en una clase y usar esos métodos desde un módulo es que «tras las bambalinas» hay más código si se define un módulo. Me refiero al código IL generado, aunque en realidad solo hay más código en el constructor del módulo, ya que el código IL de los métodos es el mismo en ambos casos.
    Después te pongo algo sobre esto (seguramente en otro post).

    Otro detalle es que en la medida de lo posible he usado declaraciones de variables explícitas en lugar de usar inferencia de tipos, para que así te resulte más fácil ver (o saber) de qué tipo de datos estoy hablando (o utilizando).

    Obtener las direcciones IP del usuario actual

    En esta primera parte del ejemplo, echaremos mano de los métodos GetHostName y GetHostAddresses de la clase Dns definida en System.Net.

    El nombre del host es necesario para saber las IPs, ya que GetHostAddresses utiliza el nombre del host (¿anfitrión?), pero mejor ve el código y después ya veremos si hay algo que aclarar.

    Empiezo con el de C# y después te muestro el de Visual Basic.

    public static string ObtenerIPs()
    {
        StringBuilder sb = new StringBuilder();
        string ipAddresses;
    
        try
        {
            var hostName = Dns.GetHostName();
            IPAddress[] addresses = Dns.GetHostAddresses(hostName);
    
            foreach (IPAddress address in addresses)
                sb.Append($"{address}, ");
    
            ipAddresses = sb.ToString().TrimEnd(", ".ToCharArray());
        }
        catch (Exception ex)
        {
            ipAddresses = "ERROR: " + ex.Message;
        }
        return ipAddresses;
    }
    

     

    Public Shared Function ObtenerIPs()
    
        Dim sb As New StringBuilder()
        Dim ipAddresses As String
    
        Try
            Dim hostName = Dns.GetHostName()
            Dim addresses As IPAddress() = Dns.GetHostAddresses(hostName)
    
            For Each address As IPAddress In addresses
                sb.Append($"{address}, ")
            Next
    
            ipAddresses = sb.ToString().TrimEnd(", ".ToCharArray())
        Catch ex As Exception
            ipAddresses = "ERROR: " & ex.Message
        End Try
        Return ipAddresses
    End Function
    

     

    Un par de cosas (tips) a destacar de ese código:
    1- La variable addresses es un array del tipo IPAddress, para obtener cada una de las direcciones IP utilizo un bucle foreach (For Each) y las agrego al StringBuilder (por aquello de que consume menos recursos que si las concateno).
    2- Como le voy añadiendo a cada IP una coma y un espacio al final (para separarlas), es necesario quitar esa coma del final, para ello utilizo TrimEnd() indicándole qué caracteres quiero quitar del final. Los caracteres indicados al método de la familia Trim deben ser caracteres, no una cadena, por eso utilizo una cadena con los caracteres a quitar del final y la convierto en array de tipo Char con ToCharArray.

    Extraer las IPv4 de una cadena con otras cosas usando expresiones regulares

    En el método que se encarga de hacer eso, utilizo la clase RegEx para mediante una cadena con «expresiones regulares» (que resultan ser buenas y no regulares 😉 ) y los casos en que ha tenido éxito, los voy agregando a un StringBuilder que después usaré (tras quitar lo que no haya que usar) para devolver como resultado de las direcciones IPv4 de esa cadena entrante.

    El código regex para obtener las IPv4 lo he adaptado de un ejemplo del sitio programador clic: Expresión regular de dirección IP.

    Aquí tienes el código de ese método para Visual Basic y C#.

    Public Shared Function LasIPv4(ipAdresses As String) As String
        Dim sb As New StringBuilder()
    
        Dim sRegExIPv4 As String = "((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)"
        Dim r As Regex = New Regex(sRegExIPv4)
    
        For Each m As Match In r.Matches(ipAdresses)
            If m.Success Then
                sb.Append($"{m.Value}, ")
            End If
        Next
    
        Return sb.ToString().TrimEnd(", ".ToCharArray())
    End Function
    

     

    public static string LasIPv4(string ipAdresses)
    {
        StringBuilder sb = new();
    
        string sRegExIPv4 = @"((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)";
        Regex r = new Regex(sRegExIPv4);
        foreach (Match m in r.Matches(ipAdresses))
        {
            if(m.Success)
            {
                sb.Append($"{m.Value}, ");
            }
        }
    
        return sb.ToString().TrimEnd(", ".ToCharArray());
    }
    

    Y esto es todo… ¡Ah! ¡No! que falta el código de cómo usar estos dos métodos.

    Cómo usar los métodos anteriores

    Eso está en el método Main del «programa» de consola.

    Aquí tienes el método Main que los utiliza.

    static void Main(string[] args)
    {
        //Console.WriteLine("Hello World!");
        Console.WriteLine("Ejemplo en C# usando .NET 5.0 para obtener las IPs y extraer con RegEx solo las IPv4.");
        Console.WriteLine();
    
        string ipAdresses = Utils.ObtenerIPs();
    
        Console.WriteLine("La cadena con todas las IPs:");
        Console.WriteLine(ipAdresses);
        string ret = Utils.LasIPv4(ipAdresses);
    
        Console.WriteLine();
        Console.WriteLine("Direcciones IPv4:");
        Console.WriteLine(ret);
    
        Console.WriteLine();
        Console.WriteLine("Pulsa INTRO para terminar.");
        Console.ReadLine();
    }
    

     

    Sub Main(args As String())
        'Console.WriteLine("Hello World!")
        Console.WriteLine("Ejemplo en Visual Basic usando .NET 5.0 para obtener las IPs y extraer con RegEx solo las IPv4.")
        Console.WriteLine()
    
        Dim ipAdresses As String = Utils.ObtenerIPs()
    
        Console.WriteLine("La cadena con todas las IPs:")
        Console.WriteLine(ipAdresses)
        Dim ret As String = Utils.LasIPv4(ipAdresses)
    
        Console.WriteLine()
        Console.WriteLine("Direcciones IPv4:")
        Console.WriteLine(ret)
    
        Console.WriteLine()
        Console.WriteLine("Pulsa INTRO para terminar.")
        Console.ReadLine()
    End Sub
    

     

    Aquí te dejo una captura del programa en ejecución.

     

    Ahora sí, esto ha sido todo amigos… 😉

    Nos vemos.
    Guillermo

    P.S.
    Aquí tienes el enlace al repositorio de GitHub con el código de ejemplo completo, tanto para Visual Basic como C# (con sus proyectos respectivos para usar con Visual Studio 2019 o superior, incluso puede que anterior, pero no lo he comprobado).
    elGuille-info/Obtener-IP-y-extraer-IPv4: Ejemplo en C# y Visual Basic de cómo obtener las IP (IPv4 e IPv6) y extraer solo las IPv4 (github.com)