[ASP .NET] Upload de Arquivo

No post de hoje veremos uma maneira bem fácil para fazer upload de arquivos com ASP .NET. Da forma que mostrarei, por exemplo, é possível verificar se já existe um arquivo como o mesmo no na pasta e dar um aviso ao usuário ou alterar o nome desse arquivo.

Utilizaremos somente:

  • Um <asp:FileUpload />; e
  • um <asp:Button />;

O segredo está no código executado no botão. A seguir, mostro o código html da página e também o codebehind necessário para fazer o upload e em seguida explico o código.

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:FileUpload ID="FileUpload1" runat="server" Width="366px" />
        <br />
        <asp:Button ID="Button1" runat="server" Text="Button" />
    </div>
    </form>
</body>
</html>
    Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click

        IO.File.WriteAllBytes("d:/" & FileUpload1.FileName, FileUpload1.FileBytes)

    End Sub

No código acima temos a procedure do botão onde executamos um métodos que cria um arquivo numa pasta do servidor.

O método que utilizamos, WriteAllBytes, está na classe File, dentro o Namespace IO. Chamamos o método passando dois parâmetros: o primeiro com o caminho onde o arquivo será gravado e um array de bytes do arquivo que selecionamos; para retornar tal array, pegamos a propriedade FileBytes do objeto FileUpload.

Importante. A pasta onde serão gravados os arquivos, deve ter permissão para escrita.

Extra

No primeiro parâmetro, onde passamos no caminho onde o arquivo será gravado, onde está FileUpload1.FileName, poderíamos colocar algo mais, para não permitir que um arquivo com um nome que já exista na pasta, seja sobreposto pelo novo. Abaixo temos o código do botão, mas com uma pequena alteração. Adicionei ao nome do arquivo que será gravado um GUID gerado pela função NewGuid. Dessa forma, o nome do arquivo ficaria com algo do tipo: fd81e93b-aa14-47b1-ab41-2779ce9138c3NOME_ORIGINAL_DO_ARQUIVO.txt.

    Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click

        IO.File.WriteAllBytes("d:/" & Guid.NewGuid.ToString & FileUpload1.FileName, FileUpload1.FileBytes)

    End Sub

Outra coisa que poderia ser feito, é gerar uma hash MD5 com o nome original do arquivo.

Espero que tenha ajudado. Até uma próxima!

Funções com assinaturas diferentes

No post de hoje, veremos como criar funções com assinaturas diferentes. Dessa forma, é possível criar funções com o mesmo nome, porém, executando tarefas diferentes. Também é possível criar vários métodos construtores[bb] para as classes, alterando os parâmetros que são recebidos. Vamos ver tudo isso logo abaixo.

Construtores das classes

Quando um código de uma classe está sendo escrito, é possível informar qual será o comportamento, ou o que será executado na classe, quando ela for executada. Esses são os métodos construtores. No Visual Basic .NET, o código para criar esse métodos está descrito abaixo.

Public Class Classe
    ' Método construtor
    Sub New()

    End Sub
End Class

Criando várias assinaturas

Quando você cria um método, este tem uma assinatura, que nada mais é, que o conjunto formado pelo nome, parâmetros e no caso de uma função que retorna valor, o tipo que será retornado. No caso de um método construtor, a assinatura não tem o nome, já que é utilizada a palavra reservada New. Abaixo temos a assinatura de um método chamado funcao1, com dois parâmetros: val1 e val2.

    Function funcao1(ByVal val1 As String, ByVal val2 As String) As String
        ' Algum código que utiliza os dos parâmetros
    End Function

Caso chamássemos esse método, seriamos obrigados a informar  os dos parâmetros. Ficaria: funcao1("Valor 1", "Valor 2"). Mas, se em algum momento, por algum motivo, fosse necessário executar essa função, sem passar esse dois parâmetros? É possível! Veja abaixo.

    Function funcao1(ByVal val1 As String, ByVal val2 As String) As String
        ' Código qualquer aqui.
    End Function
    Function funcao1() As String
        ' Código qualquer aqui.
    End Function

Se colocar esse código no seu projeto em VB .NET, tenha certeza que não vai dar erro.

O exemplo acima está muito genérico e não dá uma noção muito boa do que pode ser feito. Entretanto, não encerraria o post com essa pulga atrás da orelha a respeito da real utilidade disso. Abaixo está o código de uma classe qualquer, logo em seguida explicarei onde ela se encaixaria.

Public Class Class1
    Private _Id As Integer
    Private _Campo1 As String
    Private _Campo2 As String

    Sub New()
    End Sub

    Sub New(ByVal Campo1 As String, ByVal Campo2 As String)
        Me.Campo1 = Campo1
        Me.Campo2 = Campo2
    End Sub

    Sub New(ByVal Id As Integer, ByVal Campo1 As String, ByVal Campo2 As String)
        Me.Id = Id
        Me.Campo1 = Campo1
        Me.Campo2 = Campo2
    End Sub

    Public Property Id() As Integer
        Get
            Return _Id
        End Get
        Set(ByVal value As Integer)
            _Id = value
        End Set
    End Property
    Public Property Campo1() As String
        Get
            Return _Campo1
        End Get
        Set(ByVal value As String)
            _Campo1 = value
        End Set
    End Property
    Public Property Campo2() As String
        Get
            Return _Campo2
        End Get
        Set(ByVal value As String)
            _Campo2 = value
        End Set
    End Property

No exemplo acima, temos uma classe (Class1) com três campos. Perceba que criei três construtores para essa classe, dessa forma, posso instância essa classe sem passar parâmetros e utilizar as propriedades dessa classe, para atribuir o valores aos campos. Mas, se eu quiser instanciar a classe e já passar os valores, eu também posso.

E se você estiver utilizando o Visual Studio 2008+, ainda é possível visualizar de forma vem intuitiva os construtores.

Assinatura do método no Visual Studio 200

Espero que tenha ajudado! Até uma próxima.

Criando propriedades para classes no VB .NET

No post de hoje trago algo que abordei ligeiramente na vídeo aula Como carregar um ComboBox de maneira bem fácil, que são as propriedades de uma classe. Como bom objeto, as classe que você cria tem propriedades, como uma propriedade qualquer de um objeto qualquer. Cito aqui, por exemplo, a propriedade .Text do objeto TextBox.

Conceito dass Propriedade

É algo muito simples, porém, essencial para abordar um dos aspectos da Orientação a Objetos, que é o encapsulamento. Criando um classe e definindo suas propriedades, esses dados podem ser tratados dentro dessa classe mantendo a integridade que fora definida para cara propriedade.

Algo que deixa bastante claro essa questão do encapsulamento, são as propriedades de posicionamento de um formulário de uma aplicação em VB.NET ou C#. Você pode, por exemplo, resgatar a coordenada x de um formulário utilizando o comando:

MessageBox.Show(Formulario.Location.X)

Entretanto, ao tentar entrar com um valor para tal propriedade, receberá um mensagem de erro informando que isso não é possível. Para tanto, é necessário criar um nova localização, informando tanto x quanto y. O que é feito quanto isso acontece, fica por conta da regra utilizada para o deslocamento de um formulário, ou seja, o encapsulamento garante, tanto que os dados passados sejam tratadas da maneira correto, quanto protege a integridade da propriedade.

Criando propriedades para classes

Vamos agora ver exatamente como criar as propriedades. Abaixo está o código para a criação de duas propriedades para a classe que chamei de Dados. Em seguida explico o código.

Public Class Dados
    Private _Nome As String
    Private _ID As Integer

    Public Property Nome() As String
        Get
            Return _Nome
        End Get
        Set(ByVal value As String)
            _Nome = value
            _ID = New Random().Next(1, 10000)
        End Set
    End Property

    Public ReadOnly Property Identificador() As Integer
        Get
            Return _ID
        End Get
    End Property
End Class

Acima temos dois tipos bem diferentes de propriedades. A primeira, Nome, tanto pode ser utilizada para atribuir um valor via instancia, quanto pode  ter seu valor lido. Já a segunda, só pode ter o seu valor lido. A segui, explico linha a linha o que está acontecendo.

Linha 1: declaração da classe Dados;

Linhas 2 e 3: são declaradas duas variáveis que serão utilizadas para armazenar os valores atribuídos às propriedades;

Linha 5: declaro a primeira propriedade, Nome, ela é pública e do tipo String;

Linhas 6, 7 e 8: utilizo o comando Get para informar o que deve ser feito quanto o tentarem ler o que está na propriedade. Neste caso, somente retorno o que fora atribuído. Poderia por exemplo, aplicar a função Trim,  Replace ou mesmo ToUpper, como a propriedade pertence a classe pode ser feito qualquer coisa, inclusive retornar sempre uma String vazia;

Linhas 9, 10, 11 e 12: utilizo o comando Set, para criar os procedimentos que devem ser realizados quando for atribuído um valor à propriedade. Neste caso, simplesmente passo o valor que for atribuído, para a variável que criei anteriormente. Na declaração, é criado um parâmetro, que deve ser do mesmo tipo da propriedade. Mas, uma coisa interessante que adicionei, é que quando for atribuído um nome, a propriedade ID recebe um valor aleatório (entre 1 e 10000);

Linha 13: finalizo a declaração da propriedade Nome;

Linha 15: declaro a propriedade ID, publica do tipo Integer. Porém, diferente da anterior, adicionei a instrução ReadOnly, informando que não pode ser atribuído valor a esta variável por meio de uma instância da classe.

Linhas 16, 17 e 18: utilizo o comando Get para informar o que deve ser feito quanto o tentarem ler o que está na propriedade.

Linha 19: finalizo a declaração da propriedade ID;

Linha 20: finalizo o código da classe;

No momento que a classe for instanciada, ocorreria o seguinte:Classe criada quando instanciadaVeja que conseguimos atribuir um valor à propriedade Nome, porém, quando tentamos com o Identificador, é informado que esta propriedade é somente leitura.

E como resultado disso tudo, corrigindo o erro, temos:

Resultado do código

E dessa forma, você pode trabalhar suas classes, criando regras de negócios para seu sistema e mantendo a integridades dos dados.

Até um próxima!

Vídeo

Como carregar um ComboBox de maneira bem fácil

Nessa vídeo aula, mostro como carregar um ComboBox no Visual Basic .NET de maneira bem fácil. Para tanto, utilizarei um classe contendo os dados[bb] que serão inseridos e um DataTable que nos auxiliará na transferência dos dados.

Desse forma, você conseguirá retornar dados de função de busca, por exemplo, com uma lista (Lis(OF T)) de uma classe, mantendo a abstração da classe. Uma boa forma de trabalhar, quando está o desenvolvimento segue o padrão MVC.

Como medir o tempo gasto para executar uma tarefa

Olá galera, nesse post, vou mostrar como medir o tempo gasto para executar uma tarefa. E para tanto, mostrarei o funcionamento da classe Stopwatch.

A classe Stopwatch

A classe pública Stowatch, fornece alguns métodos para medir com um certa precisão, o tempo decorrido. Os principais métodos que utilizaremos serão:

Start

Inicia a medição. Utilização: objeto.Start()

Stop

Para a medição. Utilização: objeto.Stop()

Elapsed

Fornece o tempo decorrido entre o inicio e a parada. Retorna um TimeSpan.

Como medir o tempo gasto

No post Diferença de Performance Entre Tipos de Variáveis, mostrei uma outra forma de medição, onde escrevia o horário de inicio no console e mostrava o horário de finalização. Entretanto, dessa forma é necessário realizar um cálculo com os horários.

Utilizando a classe Stopwatch, isso já é feito pela própria classe, facilitando sua vida.

Para o post, utilizarei um projeto do tipo ConsoleApplication. Abaixo mostro o código necessário para medir o tempo decorrido para escrever no console dez mil (10000) linhas com o valor de PI. Em seguida a explicação linha a linha.

Sub Main()
        Dim sw As New Stopwatch()
        sw.Start()

        For i As Integer = 1 To 10000
            Console.WriteLine("Linha " & i & ": " & Math.PI)
        Next
        Console.WriteLine("")

        sw.Stop()

        Dim ts As TimeSpan = sw.Elapsed

        Dim TempoDecorrido As String = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds)
        Console.WriteLine("Tempo Total " + TempoDecorrido)

        Console.Read()
End Sub

Linha 2: Declaração da variável sw do tipo Stopwatch.

Linha 3:  Inicia contagem do tempo como método Start().

Linhas 5, 6, 7, 8: Executado um for para escrever as 10000 linhas com o valor de PI no console e no final, uma linha em branco para separar o que vem a seguir.

Linha 10: Para a medição com o método Stop().

Linha 12: Declara a variável ts, do tipo TimeSpan, para receber o tempo decorrido para a execução. Para tanto é utilizado o método Elapsed.

Linha 14: Declara a variável TempoDecorrido do tipo String. A variável ainda recebe o valor formatado do tempo decorrido que foi guardado na variável ts.

Linha 15: Escreve no console o tempo decorrido, já formatado.

Linha 17: Para o console visualizarmos o resultado.

E como resultado, temos.

Resultado da medição do tempo decorrido

 

O exemplo dado foi em Visual Basic .NET, mas essa classe também pode ser implementada facilmente em C#.

Bom garela, por hoje é só. Até o próximo post!