Upload utilizando Adobe Flex e ASP.NET

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:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:im="br.com.igormusardo.component.*">
	<im:uploadButton x="10" y="10" id="btUp" label="Upload Arquivo"/>
</mx:Application>

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.


Manipulador Genérico

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("<result><status>Error</status><message>No files selected</message></result>");
            return;
        }
 
        foreach (string fileKey in _context.Request.Files)
        {
            HttpPostedFile file = _context.Request.Files[fileKey];
            file.SaveAs(Path.Combine(uploadDir, file.FileName));
        }
 
        _context.Response.Write("<result><status>Success</status><message>Upload completed</message></result>");
 
    }
 
    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_<>.


Permissão

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.


Upload


Browse Window


Uploading

Faça o download do código-fonte.

Divirta-se!

19 Responses to “Upload utilizando Adobe Flex e ASP.NET”

  • Muito bom esse artigo! Parabéns!

  • @Raphael, obrigado pelo Feedback!

  • Muito bom!!! abraços!!!

  • Bruno:

    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

  • André Reis:

    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:\Work\WebSite\FlexUpload\FlexUpload\Flex\src\br\com\igormusardo\component\uploadButton.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:\Work\WebSite\FlexUpload\FlexUpload\Flex\src\FlexUpload.mxml:0]
    at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:2009]
    at mx.managers::SystemManager/initializeTopLevelWindow()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:3234]
    at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::docFrameHandler()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:3064]
    at mx.managers::SystemManager/docFrameListener()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\SystemManager.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?

  • André Reis:

    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

  • honndy:

    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?

  • Tiago:

    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

  • Felipe:

    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.

  • Rodrigo:

    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!

  • Airton Toyansk:

    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

  • Airton Toyansk:

    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:\Users\Works\Documents\Flex Builder 3\uploadASPX\src\br\com\igormusardo\component\uploadButton.as:31]
    at mx.core::Container/createComponentFromDescriptor()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:3579]
    at mx.core::Container/createComponentsFromDescriptors()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:3493]
    at mx.core::Container/createChildren()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2589]
    at mx.core::UIComponent/initialize()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:5370]
    at mx.core::Container/initialize()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2526]
    at mx.core::UIComponent/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:5267]
    at mx.core::Container/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:3305]
    at mx.core::Container/addChildAt()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2217]
    at mx.core::Container/addChild()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2140]
    at mx.core::Container/createComponentFromDescriptor()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:3681]
    at mx.core::Container/createComponentsFromDescriptors()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:3493]
    at mx.containers::Panel/createComponentsFromDescriptors()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\containers\Panel.as:1528]
    at mx.core::Container/createChildren()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2589]
    at mx.containers::Panel/createChildren()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\containers\Panel.as:1056]
    at mx.core::UIComponent/initialize()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:5370]
    at mx.core::Container/initialize()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2526]
    at mx.core::UIComponent/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:5267]
    at mx.core::Container/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:3305]
    at mx.core::Container/addChildAt()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2217]
    at mx.core::Container/addChild()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2140]
    at mx.core::Container/createComponentFromDescriptor()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:3681]
    at mx.core::Container/createComponentsFromDescriptors()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:3493]
    at mx.core::Container/createChildren()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2589]
    at mx.core::UIComponent/initialize()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:5370]
    at mx.core::Container/initialize()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2526]
    at mx.core::Application/initialize()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Application.as:846]
    at uploadASPX/initialize()[C:\Users\Works\Documents\Flex Builder 3\uploadASPX\src\uploadASPX.mxml:0]
    at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:2009]
    at mx.managers::SystemManager/initializeTopLevelWindow()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:3234]
    at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::docFrameHandler()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:3064]
    at mx.managers::SystemManager/docFrameListener()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\SystemManager.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

  • Airton Toyansk:

    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:\Users\Works\Documents\Flex Builder 3\uploadASPX\src\br\com\igormusardo\component\uploadButton.as:31]
    at mx.core::Container/createComponentFromDescriptor()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:3579]
    at mx.core::Container/createComponentsFromDescriptors()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:3493]
    at mx.core::Container/createChildren()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2589]
    at mx.core::UIComponent/initialize()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:5370]
    at mx.core::Container/initialize()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2526]
    at mx.core::UIComponent/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:5267]
    at mx.core::Container/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:3305]
    at mx.core::Container/addChildAt()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2217]
    at mx.core::Container/addChild()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2140]
    at mx.core::Container/createComponentFromDescriptor()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:3681]
    at mx.core::Container/createComponentsFromDescriptors()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:3493]
    at mx.containers::Panel/createComponentsFromDescriptors()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\containers\Panel.as:1528]
    at mx.core::Container/createChildren()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2589]
    at mx.containers::Panel/createChildren()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\containers\Panel.as:1056]
    at mx.core::UIComponent/initialize()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:5370]
    at mx.core::Container/initialize()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2526]
    at mx.core::UIComponent/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:5267]
    at mx.core::Container/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:3305]
    at mx.core::Container/addChildAt()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2217]
    at mx.core::Container/addChild()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2140]
    at mx.core::Container/createComponentFromDescriptor()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:3681]
    at mx.core::Container/createComponentsFromDescriptors()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:3493]
    at mx.core::Container/createChildren()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2589]
    at mx.core::UIComponent/initialize()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:5370]
    at mx.core::Container/initialize()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:2526]
    at mx.core::Application/initialize()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Application.as:846]
    at uploadASPX/initialize()[C:\Users\Works\Documents\Flex Builder 3\uploadASPX\src\uploadASPX.mxml:0]
    at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::childAdded()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:2009]
    at mx.managers::SystemManager/initializeTopLevelWindow()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:3234]
    at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::docFrameHandler()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:3064]
    at mx.managers::SystemManager/docFrameListener()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:2916]

    Vc saberia do que se trata e como posso resolver?

    Abs e obrigado!

    Airton Toyansk

  • Adriano:

    Mesmo com as permissões na pasta ele apresenta a seguinte mensagem: Error #2038: Erro do arquivo de E/S upload flex

Leave a Reply