Em algumas aplicações que construímos é essencial permitir ao usuário fazer o UPLOAD de arquivos.
Neste artigo vou demonstrar como construir um componente Button com a funcionalidade de fazer o upload no Adobe Flex e como preparar o ASP.NET para salvar o arquivo no servidor.
Primeiro criaremos o componente uploadButton estendendo a classe Button, conforme o código abaixo.
package br.com.igormusardo.component
{
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.ProgressEvent;
import flash.net.FileReference;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import mx.containers.TitleWindow;
import mx.controls.Button;
import mx.controls.ProgressBar;
import mx.core.Application;
import mx.managers.PopUpManager;
public class uploadButton extends Button
{
/**
* Define qual o arquivo .NET será chamado para realizar o upload físico do arquivo
*/
private const UPLOAD_URL:String = "uploadFile.ashx";
private var fr:FileReference;
private var pb:ProgressBar = new ProgressBar();
private var tw:TitleWindow;
/**
* Inicializa o FileReference e adiciona os EventListeners
*/
public function uploadButton():void {
fr = new FileReference();
fr.addEventListener(Event.SELECT, selectHandler);
fr.addEventListener(Event.OPEN, openHandler);
fr.addEventListener(ProgressEvent.PROGRESS, progressHandler);
fr.addEventListener(Event.COMPLETE, completeHandler);
}
/**
* Prepara o label da barra de progressão para informar o % de envio do arquivo
*/
private function openHandler(event:Event):void {
pb.label = "Uploading %3%%";
}
/**
* Atualiza o percentual concluído.
*/
private function progressHandler(event:ProgressEvent):void {
pb.setProgress(event.bytesLoaded, event.bytesTotal);
}
/**
* Após o upload completo, é alterado o label da barra de progressão, informando ao usuário o fim da operação
*/
private function completeHandler(event:Event):void {
pb.label = "Upload Complete";
PopUpManager.removePopUp(tw);
}
/**
* Após o arquivo selecionado o upload é executado.
*/
private function selectHandler(event:Event):void {
var request:URLRequest = new URLRequest();
request.url = UPLOAD_URL;
request.method = URLRequestMethod.POST;
openWindow()
fr.upload(request);
}
/**
* Abre popUp com a progressBar.
*/
private function openWindow():void{
tw = new TitleWindow();
tw.title = "Uploading File";
tw.width= 250;
tw.height= 80;
pb.percentHeight = 100;
pb.percentWidth = 100;
tw.addChild(pb);
PopUpManager.addPopUp(tw, this, true);
tw.x = (Application.application.width - tw.width) / 2;
tw.y = (Application.application.height - tw.height) / 2;
}
/**
* Abre a janela para escolher o arquivo a ser feito o upload.
*/
override protected function clickHandler(event:MouseEvent):void {
fr.browse();
}
}
}
O componente funciona da seguinte forma: Ao clicar sobre o botão, abrirá a janela para escolher qual arquivo será carregado para o servidor. Após escolhido o arquivo e clicado em Abrir, o Adobe Flex enviará o arquivo via POST para o ASP.NET, e o mesmo gravará o arquivo no disco do servidor.
Ainda no Adobe Flex, é preciso colocar o botão na tela, para tanto utilize o código abaixo:
Agora que encerramos a programação no Adobe Flex, precisamos ir para o .NET. Com Visual Studio aberto crie um novo Website, neste Website crie um arquivo do tipo Manipulador Genérico chamado de uploadFile.ashx, como na figura.
No arquivo uploadFile.ashx copie o código abaixo.
<%@ WebHandler Language="C#" Class="uploadFile" %>
using System.IO;
using System.Web;
using System.Web.Configuration;
public class uploadFile : IHttpHandler
{
public void ProcessRequest(HttpContext _context)
{
string uploadDir = HttpContext.Current.Server.MapPath("~/upload/");
if (_context.Request.Files.Count == 0)
{
_context.Response.Write("Error No files selected ");
return;
}
foreach (string fileKey in _context.Request.Files)
{
HttpPostedFile file = _context.Request.Files[fileKey];
file.SaveAs(Path.Combine(uploadDir, file.FileName));
}
_context.Response.Write("Success Upload completed ");
}
public bool IsReusable
{
get { return true; }
}
}
Crie a pasta upload, onde os arquivos serão salvos pelo ASP.NET, dentro do Website e conceda permissões de leitura e escrita para o usuário IUSR_<
Compile sua aplicação do Adobe Flex e copie os arquivos compilados para a pasta do Website ASP.NET.
Pronto!
Execute o Website e abra a página FlexUpload.html e faça o upload dos arquivos quiser.
Faça o download do código-fonte.
Divirta-se!
20 Response Comments
Muito bom esse artigo! Parabéns!
@Raphael, obrigado pelo Feedback!
Muito bom!!! abraços!!!
Muito bom seu artigo cara, só fica uma dúvida, porque você usa Foreach sendo que o FileReference.upload do flash envia um arquivo de cada vez??
Abraço
@Bruno eu sinceramente desconhecia que o FileRefence enviava apenas um arquivo por vez.
Sendo assim o Foreach se torna desnecessário.
Valeu a dica.
Abraços,
Igor Musardo
Caro Igor, parabens pelo artigo, estava precisando mesmo.
Encontrei um erro que já me bati porem sem solução. segue ele:
Error #2044: IOErrorEvent: não manipulado. text=Error #2038: Erro do arquivo de E/S.
at br.com.igormusardo.component::uploadButton()[C:WorkWebSiteFlexUploadFlexUploadFlexsrcbrcomigormusardocomponentuploadButton.as:31]
at mx.core::Container/createComponentFromDescriptor()
at mx.core::Container/createComponentsFromDescriptors()
at mx.core::Container/createChildren()
at mx.core::UIComponent/initialize()
at mx.core::Container/initialize()
at mx.core::Application/initialize()
at FlexUpload/initialize()[C:WorkWebSiteFlexUploadFlexUploadFlexsrcFlexUpload.mxml:0]
at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:autobuild3.2.0frameworksprojectsframeworksrcmxmanagersSystemManager.as:2009]
at mx.managers::SystemManager/initializeTopLevelWindow()[C:autobuild3.2.0frameworksprojectsframeworksrcmxmanagersSystemManager.as:3234]
at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::docFrameHandler()[C:autobuild3.2.0frameworksprojectsframeworksrcmxmanagersSystemManager.as:3064]
at mx.managers::SystemManager/docFrameListener()[C:autobuild3.2.0frameworksprojectsframeworksrcmxmanagersSystemManager.as:2916]
Será que poderia me ajudar?
Obrigado
André, o erro ocorre mesmo liberando as permissões de gravação dentro do diretório onde o upload será executo?
Sim, Igor, mesmo liberando as permissões. Liberei acesso completo no diretório e algumas outras configurações do IIS, e nada. Notei uma coisa interessante: Se eu executo a aplicação diretamente pelo Visual Studio, ele abre pela url ‘http://localhost:1197/WebSite/FlexUpload.html’, sendo que a diferença no momento é a porta que esta setada, ele executa o Upload normalmente. Diretamente executando pelo Flex ou via browser, apresenta o erro.
att.
André
André, eu já tive o mesmo problema, o meu usuário na minha máquina não conseguia fazer o upload chamando a aplicação no IIS, porém outro usuário de outra máquina chamando a aplicação na minha máquina conseguia fazer o upload. Quando fiz o deploy da aplicação para o servidor de produção, tudo funcionava perfeitamente. Não consegui entender muito bem o porque, mas só pode ser configuração de permissão no IIS. Se conseguir achar a solução por favor compartilhe.
Abraços,
Igor Musardo
bom dia Igor , tenho acompanhado e tentado desenvolver uma aplicação web com o flex 3 porem estou tendo dificuldades em relacionar o projeto do visual Studio (c#) com o flex atravez do WebOrb. Existe alguma maneira de facilmente interpretar as funções das classes em C# no Flex?
No IIS eu não sei como ajudar vocês, porém já enfrentei este mesmo erro, a solução que encontrei no apache+php foi permitir leitura+gravação+acesso no diretório e adicionar 2 linhas ao .htacess (caso não exista, criar o arquivo).
htacess:
SECFILTERENGINE OFF
SECFILTERSCANPOST OFF
Pessoal,
o upload em flex tem algum limite de tamanho para os arquivos, ou vi dizer que era no máximo 100MB. Alguem pode me ajudar?
Felipe, sinceramente desconheço tal limitação, vou dar uma pesquisada e atualizarei o post.
E se eu quiser passar um parametro para o arquivo? Como por exemplo quero passar um ID para poder gravar em um banco de dados, como eu faria isso?!
E Felipe, não há limite, porém depende da memoria liberada para uso no seu servidor. Se testar local check o arquivo php.ini, você pode permitar um número de memoria, o que pode sim limitar o tamanho do arquivo, fora isso, não há limite!
Igor,
Excelente artigo!
Executei local e funcionou maravilha… Mas não funcionou para arquivos de vídeo. Existe alguma alteração que devo fazer para subir arquivos de vídeo (no caso .avi, .mpeg e .flv)?
Abs,
Airton
Completando: ao tentar subir um arquivo acima de 4 MB, dá o erro:
Error #2044: IOErrorEvent: não manipulado. text=Error #2038: Erro do arquivo de E/S.
at br.com.igormusardo.component::uploadButton()[C:UsersWorksDocumentsFlex Builder 3uploadASPXsrcbrcomigormusardocomponentuploadButton.as:31]
at mx.core::Container/createComponentFromDescriptor()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:3579]
at mx.core::Container/createComponentsFromDescriptors()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:3493]
at mx.core::Container/createChildren()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:2589]
at mx.core::UIComponent/initialize()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreUIComponent.as:5370]
at mx.core::Container/initialize()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:2526]
at mx.core::UIComponent/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreUIComponent.as:5267]
at mx.core::Container/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:3305]
at mx.core::Container/addChildAt()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:2217]
at mx.core::Container/addChild()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:2140]
at mx.core::Container/createComponentFromDescriptor()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:3681]
at mx.core::Container/createComponentsFromDescriptors()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:3493]
at mx.containers::Panel/createComponentsFromDescriptors()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcontainersPanel.as:1528]
at mx.core::Container/createChildren()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:2589]
at mx.containers::Panel/createChildren()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcontainersPanel.as:1056]
at mx.core::UIComponent/initialize()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreUIComponent.as:5370]
at mx.core::Container/initialize()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:2526]
at mx.core::UIComponent/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreUIComponent.as:5267]
at mx.core::Container/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:3305]
at mx.core::Container/addChildAt()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:2217]
at mx.core::Container/addChild()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:2140]
at mx.core::Container/createComponentFromDescriptor()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:3681]
at mx.core::Container/createComponentsFromDescriptors()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:3493]
at mx.core::Container/createChildren()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:2589]
at mx.core::UIComponent/initialize()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreUIComponent.as:5370]
at mx.core::Container/initialize()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:2526]
at mx.core::Application/initialize()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreApplication.as:846]
at uploadASPX/initialize()[C:UsersWorksDocumentsFlex Builder 3uploadASPXsrcuploadASPX.mxml:0]
at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:autobuild3.2.0frameworksprojectsframeworksrcmxmanagersSystemManager.as:2009]
at mx.managers::SystemManager/initializeTopLevelWindow()[C:autobuild3.2.0frameworksprojectsframeworksrcmxmanagersSystemManager.as:3234]
at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::docFrameHandler()[C:autobuild3.2.0frameworksprojectsframeworksrcmxmanagersSystemManager.as:3064]
at mx.managers::SystemManager/docFrameListener()[C:autobuild3.2.0frameworksprojectsframeworksrcmxmanagersSystemManager.as:2916]
O que pode ser?
Abs,
Airton
Olá Airton,
Obrigado pelo feedback.
O ASP.NET por padrão limita o upload a 4MB, porém há como você aumentar esse limite.
Basta incluir a entrada
httpRuntime maxRequestLength=”15000″
dentro do do arquivo web.config.
Com esse entrada você passa a limitar o upload a 15MB.
Veja se assim funciona o upload de vídeos.
Abraços,
Igor Musardo
Igor, bom dia!
Obrigado pela resposta,mas o erro continua existindo…
No caso de teste local, agora está enviando qualquer arquivo abaixo do tamanho que informei no web.config. Obrigado pela dica!
Entretanto, quando subo para o servidor, mesmo dando permissão para todos os usuários à pasta upload, e independente do tamanho do arquivo (tentei com imagens de 2KB…), exibe o erro:
Error #2044: IOErrorEvent: não manipulado. text=Error #2038: Erro do arquivo de E/S.
at br.com.igormusardo.component::uploadButton()[C:UsersWorksDocumentsFlex Builder 3uploadASPXsrcbrcomigormusardocomponentuploadButton.as:31]
at mx.core::Container/createComponentFromDescriptor()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:3579]
at mx.core::Container/createComponentsFromDescriptors()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:3493]
at mx.core::Container/createChildren()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:2589]
at mx.core::UIComponent/initialize()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreUIComponent.as:5370]
at mx.core::Container/initialize()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:2526]
at mx.core::UIComponent/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreUIComponent.as:5267]
at mx.core::Container/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:3305]
at mx.core::Container/addChildAt()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:2217]
at mx.core::Container/addChild()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:2140]
at mx.core::Container/createComponentFromDescriptor()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:3681]
at mx.core::Container/createComponentsFromDescriptors()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:3493]
at mx.containers::Panel/createComponentsFromDescriptors()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcontainersPanel.as:1528]
at mx.core::Container/createChildren()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:2589]
at mx.containers::Panel/createChildren()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcontainersPanel.as:1056]
at mx.core::UIComponent/initialize()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreUIComponent.as:5370]
at mx.core::Container/initialize()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:2526]
at mx.core::UIComponent/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreUIComponent.as:5267]
at mx.core::Container/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:3305]
at mx.core::Container/addChildAt()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:2217]
at mx.core::Container/addChild()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:2140]
at mx.core::Container/createComponentFromDescriptor()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:3681]
at mx.core::Container/createComponentsFromDescriptors()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:3493]
at mx.core::Container/createChildren()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:2589]
at mx.core::UIComponent/initialize()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreUIComponent.as:5370]
at mx.core::Container/initialize()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreContainer.as:2526]
at mx.core::Application/initialize()[C:autobuild3.2.0frameworksprojectsframeworksrcmxcoreApplication.as:846]
at uploadASPX/initialize()[C:UsersWorksDocumentsFlex Builder 3uploadASPXsrcuploadASPX.mxml:0]
at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:autobuild3.2.0frameworksprojectsframeworksrcmxmanagersSystemManager.as:2009]
at mx.managers::SystemManager/initializeTopLevelWindow()[C:autobuild3.2.0frameworksprojectsframeworksrcmxmanagersSystemManager.as:3234]
at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::docFrameHandler()[C:autobuild3.2.0frameworksprojectsframeworksrcmxmanagersSystemManager.as:3064]
at mx.managers::SystemManager/docFrameListener()[C:autobuild3.2.0frameworksprojectsframeworksrcmxmanagersSystemManager.as:2916]
Vc saberia do que se trata e como posso resolver?
Abs e obrigado!
Airton Toyansk
Mesmo com as permissões na pasta ele apresenta a seguinte mensagem: Error #2038: Erro do arquivo de E/S upload flex
Gostaria de saber se alguem tem interesse em ensinar flex ?