Visual Basic em Português

Página pessoal de Jorge Paulino sobre o Visual Basic (VB.NET, ASP.NET, VB6, VBA) e algumas noticias de tecnologia

Mostrar mensagens com a etiqueta Visual Studio 2005. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta Visual Studio 2005. Mostrar todas as mensagens

VB.NET: Utilizando Stored Procedures

Um stored procedure (procedimento armazenado) é um conjunto de instruções em linguagem Transact-SQL, guardadas no servidor de forma pré-compilada. A execução pode ser feita dentro do próprio SQL ou através de uma aplicação externa, como é p caso do Visual Studio.

Os stored procedures têm algumas vantagens em relação aos comandos directos ao servidor, como é o caso de modularidade (simples de modificar sem alterar o código da aplicação), rapidez (ficam pré-compilados e ficarem em cache), entre outras, mas gostava de destacar a segurança e na protecção a ataques denominados SQL Injection.

Os SQL injection são instruções que manipulam a query, alterando a entrada de dados no servidor, através de uma aplicação externa. São uma das maiores causas de falhas de segurança das aplicações e podem destruir toda a estrutura de dados.

Para uma melhor percepção da importância dos stored procedures e da protecção aos SQL Injection, recomendo a visualização de um webcast gratuito, disponível na MSDN Brasil de Luciano Moreira: https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=pt-BR&EventID=1032383827&CountryCode=BR

A utilização de stored procedures em Visual Basic.Net é bastante simples. Cria-se a tabela, depois um novo stored procedure e para finalmente o código.

O seguinte exemplo mostra como criar um stored procedure e como é simples, através do código, mostrar, inserir, modificar ou apagar dados. Não serão mostrados todos os exemplos, uma vez que as principais diferenças estão nos comandos T-SQL e não propriamente no código.

Para o seguinte exemplo foi criada uma tabela simples, com o nome produtos, com três campos apenas:

 

ID               INT (primary key)

codigo        INT

produto       VARCHAR(50)

 

Um exemplo simples de um stored procedure para listar todos os dados da tabela produtos seria:

CREATE PROCEDURE dbo.sp_produtos
AS
BEGIN 
            SELECT * FROM produtos;
END


Após a gravação do stored procedure a instrução CREATE passa a ALTER, porque o que será feito posteriormente é uma alteração ao procedimento e não uma criação. Para o exemplo será feito um stored procedure um pouco mais complexo, que permita a pesquisa por código ou por produto (ou parte do nome).

/*
Stored Procedure que permite a pesquisa por
código ou nome (ou parte do nome) do produto
*/

CREATE PROCEDURE dbo.sp_produtos

            /** Indicação dos parâmetros de entrada com um valor por defeito
            o que permite que não sejam indicados através do código */

            @codigo INT = NULL
            @produto VARCHAR(50) = NULL       

AS
BEGIN 

            SELECT
            FROM produtos

           
-- Definição do filto da pesquisa
            WHERE (@codigo IS NULL OR codigo = @codigo) 
            AND (@produto IS NULL OR produto LIKE '%'+ @produto + '%');   

END

 
Depois no código de Visual Basic.Net:

        ' Informação da Connection String
        Dim myConnectionString As String = _
       "Data Source=.\SQLEXPRESS;AttachDbFilename='c:\myDatabase.mdf';Integrated Security=True;User Instance=True"

        ' Ligação à base de dados
        Using connection As New SqlConnection(myConnectionString)
            connection.Open()

            ' Indica o nome do Stored Procedure e que o tipo do comando
            Dim command As New SqlCommand("sp_produtos", connection)
            command.CommandType = CommandType.StoredProcedure 

            ' Caso o código tenha sido indicado 
            If txtCodigo.Text <> String.Empty Then
                command.Parameters.Add("@codigo", SqlDbType.Int).Value = txtCodigo.Text
            End If 

            ' Caso o produto tenha sido indicado 
            If txtProduto.Text <> String.Empty Then
                command.Parameters.Add("@produto", SqlDbType.VarChar).Value = txtProduto.Text
            End If

            ' Executa o comando e guarda o resultado no SqlDataReader
            Dim reader As SqlDataReader = command.ExecuteReader()

            ' Caso tenha resultados
            If reader.HasRows Then 

                ' Ciclo que irá mostrar os produtos encontrados
                While reader.Read
                    Dim result As String = _
                        String.Format("{0}-{1}-{2}", reader.Item(0), reader.Item(1), reader.Item(2))
                    Debug.WriteLine(result)
                End While

                Debug.WriteLine("Fim da pesquisa!") ' Informação no fim da pesquisa

            Else

                ' Caso não tenham sido encontrados produtos ...
                Debug.WriteLine("Não foram encontrados produtos!")

            End If

            reader.Close()
            reader = Nothing

        End Using   'connection


Este exemplo mostra como listar (na Immediate Window) os produtos de uma tabela, permitindo ou não, indicar dados de modo a estabelecer um filtro de pesquisa. Para inserir dados, modificar ou mesmo apagar é necessário adequar o stored procedure e o código é bastante semelhante, como já mostrado em artigos anteriores.


Este artigo pretende apenas mostrar, de uma forma geral, alguns dos benefícios dos stored procedures e a sua importância na melhoria de performance e segurança dos dados.

 

PS: Como sempre, qualquer dúvida, comentário ou correcção ao artigo é sempre bem vinda!


VB.NET: Dicas de Programação #10

Tratamento de Erros

Teoricamente é possível criar uma aplicação em que todos os erros são tratados de modo a não acontecerem, ou seja, nunca existirem. Esta teoria na realidade não acontece por vários motivos, sendo como principal o facto do programador não contemplar ou não conseguir contemplar todos os possíveis problemas durante o desenvolvimento.

Uma correcta gestão dos erros na aplicação evita mensagens difíceis de analisar, aplicações a fecharem inesperadamente e torna, obviamente, as aplicações mais profissionais e robustas.

Com a introdução do .NET apareceu um novo método em substituição ao On Error Go To <label>. O método Try … Catch … End Try permite criar um bloco no código onde o erro é verificado e tratado. É simples de implementar, muito eficiente e com diversas variações que dão uma maior flexibilidade. Num exemplo simples funciona desta forma:

        Try

            ' código do programa

        Catch ex As Exception
                     MessageBox.Show(ex.Message)

        End Try


No entanto existem mais variações que permitem uma melhor gestão dos erros. São o caso de instruções com o Finally, que permite que o código execute sempre, ou seja, caso exista ou não erro, e o When, que permite decidir se o erro é ou não “agarrado”.

Além disso pode-se a qualquer momento dizer que ocorreu um erro e forçar a mensagem sem duplicar código, através da instrução Throw.

Eis um pequeno exemplo, com a alteração de um valor ou outro, permite alterar a forma como a mensagem/erro é tratado, e mostra alguns métodos que é possível implementar:

    Sub CalculaResultado(ByVal valor1 As Integer, ByVal valor2 As Integer, ByVal ignoraErro As Boolean)

        Try 

            ' Verifica se os valores são zero
            If valor1 = 0 AndAlso valor2 = 0 Then

                ' Define uma nova ArgumentNullException
                Dim msgErro As String = "Os valores a calcular não podem ser os dois 0"

                Throw New ArgumentNullException(msgErro, New Exception(String.Empty))

            End If

            ' Caso o valor 1 seja zero, vai ser originada uma 
            ' ArithmeticException devido à divisão por zero
            Dim valorfinal As Integer = valor2 / valor1

            ' Neste exemplo caso o resultado seja menor que 10 
            ' origina uma Exception simples
            If valorfinal < 10 Then

                Throw New Exception("O valor final não é valido")

            End If


       
Catch ex As ArithmeticException When ignoraErro = False
            Debug.WriteLine("Não é permitida uma divisão de um valor por zero") 

        Catch ex As ArgumentNullException When ignoraErro = False
            Debug.WriteLine(ex.Message)

        Catch ex As Exception
            Debug.WriteLine(ex.Message)

        Finally
            Debug.WriteLine("Fim do exemplo!")
        End Try


   
End Sub

 

E alguns resultados:

            ' Calcula o resultado com números a zero
            CalculaResultado(0, 0, False)

           
Os valores a calcular não podem ser os dois 0
           
Fim do exemplo!

            ' Provoca uma divisão por zero
            CalculaResultado(0, 50, False)

Não é permitida uma divisão de um valor por zero
Fim do exemplo!

            ' Provoca uma divisão por zero, mas não trata o erro
            CalculaResultado(0, 50, True)

           
Arithmetic operation resulted in an overflow.
           
Fim do exemplo!

' Calcula onde o resultado é inferior a 10
CalculaResultado(45, 50, False)

O valor final não é valido
Fim do exemplo!

 

 

Inserir Imagens no SQL Server

Em dois artigos anteriores, foram abordadas algumas formas de trabalhar com dados num servidor SQL. Gestão de Dados em SQL Server - Parte I e Gestão de Dados em SQL Server - Parte II mostraram como inserir, modificar, apagar e ler dados, mas no entanto podem-se também inserir imagens e não basta simplesmente indicar qual é a imagem.

Existem duas alternativas para a gestão de imagens: guardar apenas a localização e colocar a imagem no servidor ou gravar a imagem directamente num campo.

Para inserir a imagem é necessário ler, gravar num array de bytes e finalmente utilizar esse array para gravar na base de dados.

Eis um exemplo de como o fazer:

        ' Define a Connection String
        Dim myConnectionString As String = _
            "Data Source=.\SQLEXPRESS;AttachDbFilename='c:\myDatabase.mdf';Integrated Security=True;User Instance=True"

        Try

            ' Cria um novo FileStream para leitura da imagem
            Dim fs As New IO.FileStream("c:\image.jpg", IO.FileMode.Open, IO.FileAccess.Read)

            ' Cria um array de Bytes do tamanho do FileStream 
            Dim ImageData(fs.Length() - 1) As Byte

            ' Lê os bytes do FileStream para o array criado
            fs.Read(ImageData, 0, ImageData.Length)

            ' Fecha o FileStream ficando a imagem guardada no array
            fs.Close()

            Using connection As New SqlClient.SqlConnection(myConnectionString)

               
' Define o comando Transact-SQL para inserir dados
                Dim SQL As String = "INSERT INTO contacts ([name],[img]) VALUES (@name,@img);"
                Dim command As New SqlClient.SqlCommand(SQL, connection)

                ' Define os parâmetros para a inserção de dados, onde está o array 
                ' de bytes(imagem) a ser inserida. O tipo do campo é Image
                command.Parameters.Add("@name", SqlDbType.VarChar).Value = "jpaulino"
                command.Parameters.Add("@img", SqlDbType.Image).Value = ImageData
                connection.Open()

                ' Insere os campos no SQL
                command.ExecuteNonQuery()

            End Using

        Catch ex As Exception
            MessageBox.Show(ex.Message, My.Application.Info.Title, MessageBoxButtons.OK, MessageBoxIcon.Error)

        End Try

 

PS: Como sempre, qualquer dúvida, comentário ou correcção ao artigo é sempre bem vinda!


VB.NET: Criando uma Label com sombra

No VB.NET não está disponível uma label que permita criar um sombreado no texto de modo a tornar-lo com mais destaque. Esta propriedade é muito comum em ambiente Office, em programas como o Excel, Word, etc, mas está disponível também em muitos outros programas.


Para criar uma label que permita criar um sombreado é preciso desenhar o texto através do namespace System.Drawing. O conceito é bastante simples: a label escreve um texto, que será a sombra, e através do evento onPaint() desenha-se o texto que fica por cima.

Depois é escondida a propriedade ForeColor (que define a cor do texto) porque esta não será a cor do texto mas sim da sombra e são criadas algumas novas propriedades:

  • OffsetX (define o offset, ou desvio, na vertical face ao texto inicial)
  • OffsetY (define o offset, ou desvio, na horizontal face ao texto inicial)
  • ForeColorFront (define a cor que fica por cima)
  • ForeColorBack (define a cor que fica por baixo – sombra)

É necessário então criar uma nova classe e utilizar o seguinte código:

Imports System.Drawing
Imports System.ComponentModel

Public Class ShadowLabel
    Inherits Label   

#Region "Properties"

    Private m_offsetX As Integer
    Private m_offsetY As Integer
    Private m_ForeColorFront As Color

    ''' <summary>
    ''' Definição do offset em X
    ''' </summary>
    <DefaultValue(0)> _
    <Category("Shadow")> _
    <Description("Definição do offset em X")> _
    Public Property OffsetX() As Integer
        Get
            Return m_offsetX
        End Get
        Set(ByVal value As Integer)
            m_offsetX = value
            Me.Invalidate()
        End Set
    End Property

    ''' <summary>
    ''' Definição do offset em Y
    ''' </summary>
    <DefaultValue(-1)> _
    <Category("Shadow")> _
    <Description("Definição do offset em Y")> _
    Public Property OffsetY() As Integer
        Get
            Return m_offsetY
        End Get
        Set(ByVal value As Integer)
            m_offsetY = value
            Me.Invalidate()
        End Set
    End Property

    ''' <summary>
    ''' Definição da cor da frente
    ''' </summary>
    <DefaultValue(GetType(Color), "RoyalBlue")> _
    <Category("Shadow")> _
    <Description("Definição da cor da frente")> _
    Public Property ForeColorFront() As Color
        Get
            Return m_ForeColorFront
        End Get
        Set(ByVal value As Color)
            m_ForeColorFront = value
            Me.Invalidate()
        End Set
    End Property

    ''' <summary>
    ''' Definição da cor de sombreado
    ''' </summary>
    <DefaultValue(GetType(Color), "White")> _
    <Category("Shadow")> _
    <Description("Definição da cor de sombreado")> _
    Public Property ForeColorBack() As Color
        Get
            Return Me.ForeColor
        End Get
        Set(ByVal value As Color)
            Me.ForeColor = value
            Me.Invalidate()
        End Set
    End Property



   
' Serve apenas para definir que a propriedade ForeColor
    ' não está disponível para alterar no editor e no design
    <Browsable(False), EditorBrowsable(EditorBrowsableState.Never)> _
    Public Overrides Property ForeColor() As System.Drawing.Color
        Get
            Return MyBase.ForeColor
        End Get
        Set(ByVal value As System.Drawing.Color)
            MyBase.ForeColor = value
        End Set
    End Property   

#End Region


   
' Define algumas propriedades por defeito
    Public Sub New()

        ' Definição dos valores iniciais de offset
        Me.OffsetX = 0
        Me.OffsetY = -1

        ' Definição das cores iniciais do texto
        Me.ForeColorFront = Color.RoyalBlue
        Me.ForeColorBack = Color.White   

    End Sub


   
' No evento Paint desenha o texto
    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)

        MyBase.OnPaint(e)

        ' Desenha o texto que fica na frente
        Dim BackBrush As New SolidBrush(Me.ForeColorFront)
        e.Graphics.DrawString(Me.Text, Me.Font, BackBrush, OffsetX, OffsetY, StringFormat.GenericDefault)
        BackBrush.Dispose()

    End Sub


End
Class


No final é preciso compilar a aplicação e o controlo estará disponível na toolbar.

Este é um exemplo que pretende mostrar como criar uma label com uma sombra, mas também como utilizar algumas funcionalidades do namespace Drawing.

 

PS: Como sempre, qualquer dúvida, comentário ou correcção ao artigo é sempre bem vinda!


VB.NET: Criptografia - TripleDES

A segurança de dados é algo fundamental em qualquer aplicação e cada vez mais é um motivo de preocupação. Quando se guarda determinado tipo de informação, numa base de dados por exemplo, é importante que a mesma esteja segura, principalmente em alguns campos como é o caso de passwords, números de cartões de crédito, informações confidenciais, etc.

É aí que a criptografia entra, através da encriptação ou codificação de dados. A encriptação é a transformação de informação electrónica de texto legível em texto incompreensível, através de um cifra, também conhecido por algoritmo.

Este processo é bastante complexo mas a .Net Framework através da Namespace System.Security.Cryptography simplifica bastante, tornando-o acessível e fácil de utilizar. Existem diversas classes disponíveis que implementam diferentes tipos de encriptação, como é o caso de: AES (Advanced Encryption Standard), DES (Data Encryption Standard), RC2 (Rivest Cipher), Rijndael, TripleDES (Triple Data Encryption Standard), entre outras.

 

De entre todos os métodos de encriptação disponíveis, alguns são mais seguros do que outros, como é o caso do Rijndael ou do AES. No entanto e para este exemplo, será mostrado a utilização do TripleDES, por ser bastante simples de implementar.

Como curiosidade o TripleDES baseia-se no algoritmo DES que foi utilizado pelo governo norte-americano e que, actualmente, pode ser decifrado. Posteriormente foi desenvolvida uma versão melhorada onde o algoritmo corre três vezes com duas chaves simétricas: o TripleDES.


Para a implementação de uma encriptação utilizando o algoritmo TripleDES devemos criar a seguinte classe:


Imports
System.Text
Imports System.Security.Cryptography

''' <summary>
''' Encriptação simples usando TripleDES
''' (Triple Data Encryption Standard)
''' </summary>
Public Class Crypto

    Private Shared TripleDES As New TripleDESCryptoServiceProvider
    Private Shared MD5 As New MD5CryptoServiceProvider

    ' Definição da chave de encriptação/desencriptação
    Private Const key As String = "CHAVE12345teste"

    ''' <summary>
    ''' Calcula o MD5 Hash 
    ''' </summary>
    ''' <param name="value">Chave</param>
    Public Shared Function MD5Hash(ByVal value As String) As Byte()

        ' Converte a chave para um array de bytes 
        Dim byteArray() As Byte = ASCIIEncoding.ASCII.GetBytes(value)
        Return MD5.ComputeHash(byteArray)

    End Function   

    ''' <summary>
    ''' Encripta uma string com base em uma chave
    ''' </summary>
    ''' <param name="stringToEncrypt">String a encriptar</param>
    Public Shared Function Encrypt(ByVal stringToEncrypt As String) As String   

        Try

            ' Definição da chave e da cifra (que neste caso é Electronic
            ' Codebook, ou seja, encriptação individual para cada bloco)
            TripleDES.Key = Crypto.MD5Hash(key)
            TripleDES.Mode = CipherMode.ECB   

            ' Converte a string para bytes e encripta
            Dim Buffer As Byte() = ASCIIEncoding.ASCII.GetBytes(stringToEncrypt)
            Return Convert.ToBase64String(TripleDES.CreateEncryptor().TransformFinalBlock(Buffer, 0, Buffer.Length))   

        Catch ex As Exception
            MessageBox.Show(ex.Message, My.Application.Info.Title, MessageBoxButtons.OK, MessageBoxIcon.Error)

            Return String.Empty

        End Try   

    End Function

  

    ''' <summary>
    ''' Desencripta uma string com base em uma chave
    ''' </summary>
    ''' <param name="encryptedString">String a decriptar</param>
    Public Shared Function Decrypt(ByVal encryptedString As String) As String   

        Try

            ' Definição da chave e da cifra
            TripleDES.Key = Crypto.MD5Hash(key)
            TripleDES.Mode = CipherMode.ECB   

            ' Converte a string encriptada para bytes e decripta
            Dim Buffer As Byte() = Convert.FromBase64String(encryptedString)
            Return ASCIIEncoding.ASCII.GetString(TripleDES.CreateDecryptor().TransformFinalBlock(Buffer, 0, Buffer.Length))

        Catch ex As Exception
            MessageBox.Show(ex.Message, My.Application.Info.Title, MessageBoxButtons.OK, MessageBoxIcon.Error)

            Return String.Empty

        End Try   

    End Function

End Class

   

Depois, para a implementar na aplicação, é só necessário 
   

        Dim source As String = "vbtuga"

        ' Mostra o texto original
        Debug.WriteLine("Texto original  : " & source)

        ' Encripta a string
        Dim result As String = Crypto.Encrypt(source)

        ' Mostra o resultado da encriptação
        Debug.WriteLine("Texto encriptado: " & result)

        ' Decripta e mostra o texto original
        Debug.WriteLine("Texto decriptado: " & Crypto.Decrypt(result))   

   

Neste pequeno teste, o resultado é o seguinte (na Immediate Window):

Texto original     : vbtuga

Texto encriptado: 6ldtC7GfpGg=

Texto decriptado: vbtuga


Este artigo é um exemplo de encriptação de forma a tornar os dados e as aplicações mais seguras. Brevemente, assim que possível, irei mostra mais dois exemplos de encryptação em AES e
Rijndael.

Exemplo do artigo: DOWNLOAD DO FICHEIRO
   

PS: Como sempre, qualquer dúvida, comentário ou correcção ao artigo é sempre bem vinda!




Microsoft Office Especialist

Membro da Comunidade
Experts-Exchange


Administ. da Comunidade
Portugal-a-Programar



Twitter

Artigos no CodeProject

Artigos no CodeProject

Subscrever Novidades

Endereço de Email:

Delivered by FeedBurner

Seguidores

Histórico