

| com exemplos em VB |
| Componente para deixar forms em Vb semelhantes às telas do winnamp |
| Componente para colocar sua aplicação VB no Systray |
| Componente para transformar sua aplicação VB em serviço |
| Ferramentas úteis para quem usa Olap Server |
| |

![]() |
||||||||
|
|
||||||||
Por Dennes
Torres dennes@bufaloinfo.com.brDennes Torres possui as certificações MCAD, MCSD,MCSE, MCDBA e MCT. Atualmente atua Como diretor da Búfalo Informática, líder do grupo de usuários DevASPNet no Rio de Janeiro e membro da liderança dos grupos getWindows e devSQL, também do Rio de Janeiro, podendo sempre ser encontrado na lista de discussão do grupo DevASPNet (devaspnet-subscribe@yahoogrupos.com.br) bem como nas reuniões do grupo. Mantém dois blogs em http://cidadaocarioca.blogspot.com e http://br.thespoke.net/blogs/dennes/default.aspx |
|
|
|
|
| Criando uma ProgressBar para o Upload de arquivos | |
|
|
|
Um dos grandes desafios da web é controlar adequadamente o upload de arquivos, permitindo inclusive a exibição de uma barra de progresso durante o upload de arquivos muito grandes.
Para fazer isso precisamos ter algum controle sobre a transferência de dados entre o servidor e o client. Podemos obter isso através do uso de HTTPModules. Neste exemplo irei utilizar um HTTP Module gratuito chamado ABCUpload ( http://www.websupergoo.com/downloadftp.htm )
Porém o HTTPModule é apenas parte dos desafios de um controle de upload. Precisamos conseguir uma comunicação adequada entre client e server para poder mostrar uma barra de progresso durante o upload de arquivos.
O botão de submit no formulário de upload de arquivos precisará não apenas fazer o submit, mas abrir um popup no qual será mostrada a barra de progresso e só depois fazer o submit. Por isso precisaremos utilizar javascript neste botão.
Para simplificar o trabalho dos desenvolvedores que forem futuramente lidar com isso podemos criar um custom web control que herde características de um Button e adicione o javascript necessário.
Para que um custom control possa incluir código javascript na páginas devemos utilizar métodos do objeto Page. Veja como fica nosso exemplo :
1 Public Class ButtonUpload
2 Inherits System.Web.UI.WebControls.Button
3
4 Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)
5 Me.Page.RegisterClientScriptBlock("btnUpScript", "<script language=""javascript"" src=""/aspnet_client/btnUpload/v1/upload.js""></script>")
6
7
8 Me.Page.RegisterOnSubmitStatement("btnUpSub", "return DoUpload(this)")
9
10
11 MyBase.OnPreRender(e)
12 End Sub
13 End Class
Utilizando o RegiterOnsubmitStatement podemos registrar uma instrução que deverá ser rodada no momento do submit do form. Já o RegisterClientScriptBlock nos permite registrar um bloco de script client sem uma relação específica com eventos. No caso utilizamos para registrar uma chamada a um arquivo javaScript.
Observe que cada script registrado possui um nome específico. Isso porque poderíamos estar utilizando mais de uma instância deste botão em uma página. Utilizando o nome na hora de registrar o script o objeto Page se encarrega de impedir a duplicação do código javascript.
O arquivo Upload.JS encontra-se em um caminho padrão. Poderia estar em qualquer outro local, claro, mas este é um caminho padrão para arquivos javascript que sejam utilizados por WebControls. Dentro do diretório aspnet_client, na raiz do site, cria-se um subdiretório para o webControl e por fim um subdiretório para a sua versão.
Veja como fica o código javaScript deste arquivo :
function DoUpload(inForm) {
theFeats = "height=160,width=600,location=no,menubar=no,resizable=no,scrollbars=no,status=no,toolbar=no";
theUniqueID = Math.floor(Math.random() * 1000000) * ((new Date()).getTime() % 1000);
window.open("progressbar.aspx?ProgressID=" + theUniqueID, theUniqueID, theFeats);
thePos = inForm.action.indexOf("?");
if (thePos >= 0)
inForm.action = inForm.action.substring(0, thePos);
inForm.action += "?UploadID=" + theUniqueID;
inForm.submit();
return true;
}
Esta função javascript recebe como parâmetro o Form. Calcula um ID unico para o upload que está sendo realizado e faz um Window.Open de uma janela para a exibição da ProgressBar. Observe que em uma versão 2 deste WebControl tanto as características da janela como o nome da página que é aberta poderiam se transformar em parâmetros.
Feito isso a função edita o Action do form de forma a adicionar o parâmetro com o ID do upload, mantendo assim sincronizado o ID entre a página que está fazendo o Upload e a página com a barra de progresso.
Por fim esta função provoca o submit do form e retorna true, garantindo que seja dada continuidade ao submit.
Neste ponto, um a parte : Quem foi que disse que não é preciso conhecer javascript para desenvolver para web ?
Feito isso podemos montar a página de upload utilizando um FileField (aba HTML na toolbox) e nosso botão. Lembrando, claro, que o botão precisará ser compilado e adicionado na toolbox, clicando com o botão direito na toolbox e utilizando "Add new item".

Vamos então programar o processo de Upload utilizando o ABCUpload, já que este componente nos dará automaticamente as estatisticas do upload, nos permitindo montar a barra de progresso. Veja como fica :
15 Private Sub ButtonUpload1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonUpload1.Click
16 Dim up As New WebSupergoo.ABCUpload5.Upload
17
18 up.Files("File1").SaveAs("c:\upload\" & IO.Path.GetFileName(File1.PostedFile.FileName))
19
20
21
22 Label1.Visible = True
23 End Sub
O label1 tem uma mensagem de "Concluido". Utilizei um diretório fixo para guardar os arquivos recebidos.
O ABCUpload pede uma série de tags dentro do Web.Config para seu funcionamento. Veja o que deve ser adicionado dentro do Configuration :
<configSections>
<sectionGroup name="websupergoo.abcupload">
<section name="advanced" type="System.Configuration.SingleTagSectionHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<section name="notes" type="System.Configuration.SingleTagSectionHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
<section name="queryfields" type="System.Configuration.SingleTagSectionHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
</sectionGroup>
</configSections>
<websupergoo.abcupload>
<advanced
enableProgressBar="true"
fixCorruptUploads="true"
enableLargeUploads="true"
multiThreaded="true"
optimization="true"
chunkSize="8192"
tempDirectory=""
logExceptions="false"
serial=""
/>
<notes
exception = "An error occurred. {0}"
connecting = "Connecting..."
gettingSize = "Getting upload size..."
checkingSize = "Checking upload size..."
preloading = "Getting preloaded data..."
transferring = "Transferring data..."
finishing = "Finishing..."
uploadStopped = "Upload stopped unexpectedly..."
uploadTooLarge = "Upload size is greater than the maximum allowed..."
/>
<queryfields
uploadID = "UploadID"
dumpPath = ""
/>
</websupergoo.abcupload>
Veja as tags que devem ser adicionadas no System.Web :
<httpModules> <add name="Progress" type="WebSupergoo.ABCUpload5.ProgressModule, ABCUpload5, Version=5.3.0.0, Culture=neutral, PublicKeyToken=1f89539196ce5fbf"/> </httpModules>
<httpRuntime maxRequestLength="1048576" executionTimeout="1200" />
Observe a presença de um HTTPModule, para controlar o upload dos arquivos e indicar o percentual já carregado. A tag httpRuntime é padrão do ASP.NET, alterando os limites máximos para o processo de upload. Quanto a isso já foi publicado um artigo no site do grupo devASPNet, dêem uma olhada em http://www.devaspnet.com.br/colunas2/coluna2101.aspx
Agora vamos montar a barra de progresso. Precisaremos de uma tabela com uma célula colorida que aumente de tamanho conforme o percentual de progresso, até chegar a 100%. Eis ai mais um Custom Web Control que podemos criar.
Desta vez não temos um controle do qual possamos herdar diretamente. Se herdarmos de HTMLTable herdaremos também todas as funcionalidades de personalização da tabela (adicionar e remover linhas e células) e nosso webControl não precisa disso, tem um formato fixo.
Portanto nosso webControl irá herdar da classe WebControl, porém desejaremos que ele seja renderizado como uma tabela. Para isso devemos fazer override das propriedades TagKey e TagName. Veja como fica :
26 <ToolboxData("<{0}:ProgBar runat=server></{0}:ProgBar>")> _
27 Public Class ProgBar
28 Inherits System.Web.UI.WebControls.WebControl
29
30
31 Protected Overrides ReadOnly Property TagKey() As System.Web.UI.HtmlTextWriterTag
32
33
34 Get
35 Return (System.Web.UI.HtmlTextWriterTag.Table)
36 End Get
37 End Property
38
39 Protected Overrides ReadOnly Property TagName() As String
40
41
42 Get
43 Return ("Table")
44 End Get
45 End Property
46
47 End Class
Com isso determinamos que a renderização deve ser feita como Table. Essa nossa tabela terá duas linhas com células, que podemos chamar de controles filho (ChildControls). Então precisaremos fazer override no método CreateChildControl. Veja como fica :
25 Protected Overrides Sub CreateChildControls()
26 Dim tr As New HtmlTableRow
27 Dim tc As New HtmlTableCell
28 tc.InnerHtml = "Fazendo Upload :"
29 tc.ColSpan = 2
30 tr.Cells.Add(tc)
31 Me.Controls.Add(tr)
32 tr = New HtmlTableRow
33 tc = New HtmlTableCell
34 tc.Width = Percentual & "%"
35 tc.Height = 25
36 tc.BgColor = BarColor.ToString
37 tr.Cells.Add(tc)
38 tc = New HtmlTableCell
39 tc.BgColor = "white"
40 tc.Width = 100 - Percentual & "%"
41 tr.Cells.Add(tc)
42 Me.Controls.Add(tr)
43 MyBase.CreateChildControls()
44 End Sub
Em WebControls que fazem isso - overrides do createChildControls - precisamos garantir que nossos controles filho serão criados sempre que forem necessários. Para isso devemos chamar o método EnsureChildControls nos locais adequados - Na propriedade Controls e no método Render. Veja como fica :
46 Public Overrides ReadOnly Property Controls() As System.Web.UI.ControlCollection
47
48
49 Get
50 EnsureChildControls()
51 Return (MyBase.Controls)
52 End Get
53 End Property
54
55 Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
56
57
58 EnsureChildControls()
59 MyBase.Render(writer)
60 End Sub
Além disso devemos observar que utilizamos no método CreateChildControls 2 propriedades : Percentual e BarColor. Percentual é utilizada para determinar o percentual concluido - determinando como a barra de progresso vai ser renderizada. Veja como fica o código destas propriedades :
62 Dim _barColor As System.Drawing.Color = System.Drawing.Color.Red
63 Dim _percentual As Integer
64
65 Public Property Percentual() As Integer
66 Get
67 Return (_percentual)
68 End Get
69 Set(ByVal Value As Integer)
70 _percentual = Value
71 DirectCast(Me.Controls(1), HtmlTableRow).Cells(0).Width = Percentual & "%"
72
73
74 DirectCast(Me.Controls(1), HtmlTableRow).Cells(1).Width = 100 - Percentual & "%"
75
76
77 End Set
78 End Property
79
80 Public Property BarColor() As System.Drawing.Color
81 Get
82 Return (_barColor)
83 End Get
84 Set(ByVal Value As System.Drawing.Color)
85 _barColor = Value
86
87 DirectCast(Me.Controls(1), HtmlTableRow).Cells(0).BgColor = Value.ToString
88
89
90 End Set
91 End Property
Por fim, vamos programar a página ProgressBar.aspx para exibir a barra de progresso. Basta programar o Load, veja como fica :
94 Dim prg As New WebSupergoo.ABCUpload5.Progress(Request.QueryString("ProgressID"))
95
96 ProgBar1.Percentual = prg.PercentDone
97 If prg.PercentDone >= 100 Then
98
99 Page.RegisterStartupScript("fechar", "<script>top.close</script>")
100
101
102 End If
Utilizamos mais uma vez o RegisterStartUpScript, desta vez para garantir que o popup feche-se automaticamente quando o upload terminar.
Pronto, temos uma barra de progresso para o upload de arquivos. Espero ter inspirado vocês a criar muitas versões inovadoras desta barra de progresso.

Veja abaixo os comentários já enviados :
| Nome : Mário Guima | E-Mail : mguimaraes@cmsolucoes.com.br |
| Boa tarde Dennes, sempre acompanho suas matérias e gostei muito desta matéria, sobre Proggress Bar no momento do UpLoad. Sendo que fiquei com uma dúvida quanto a utilização do HTTP Module chamado ABCUpload. Pois não entendi se terei que instalar alguma coisa no servidor, provedor o qual tenho meu site, ou se isso será automático!! Você poderia esclarecer este ponto por favor? Desde já agradeço |
|
| Nome : Dennes | E-Mail : dennes@bufaloinfo.com.br |
| Oi ! No .NET as instalações não exigem registro, as dlls necessárias podem ser copiadas para seu diretório bin []'s Dennes |
|
| Nome : gonzolder | E-Mail : gonzolder@mail.com |
| ja krevetko! Vsem sasat'! | |
| Nome : Papayyz | E-Mail : Papaysq@mail.com |
| Thank you! | |
| Nome : Papaykl | E-Mail : Papayrm@mail.com |
| Thank you! | |
| Nome : rafael | E-Mail : rafael.lima.jf@gmail.com |
| muito bom .............. | |
| Nome : jadson | E-Mail : jadsondesigner@hotmail.com |
| cara muito impressionante mais nunca consigo concluir por falta de experiência teria como você me mandar os arquivos abraço, jadson jadsondesigner@hotmail.com |
|
| Nome : | E-Mail : |