Example: File upload using ASP.Net and a progress bar

Hi there,

 

I found a few examples of file upload from Corona using php but I needed to use .Net (VB.Net).

 

In reality you’d probably only want to use this to upload some captured content like an image from the camera or a recorded audio file. This example just uploads a file which is already packaged in with your app but there are plenty of other examples that will show you how to access files you’ve saved to the documents directory yourself.

 

There are three parts to this: the LUA file, the ASP.Net file and the web.config file… the code in the LUA could be a lot cleaner if split into individual classes etc. but for ease of adding it all in one place I’ve just lumped it all into the main.lua so this example should work right off the shelf.

 

Things you need to do:

 

LUA:  Make sure the aspxPath and fileName variables in main.lua are set to point to the ASP.Net script on your server and the name of the file you are trying to upload (including the file extension). Also ensure the uploadTimeout value is set (in seconds) to a value which will allow your file to upload. I haven’t included any error handling for if this is exceeded so that’s something you’ll need to look into if for example someone tries to upload over a slower connection…

 

ASP.Net Make sure the str_savePath variable in the .Net file points to the path you want to save your uploaded file to on your server. For some reason my original code replaced all the plus signs in the mime.b64 encoded string with spaces or line breaks. I have added some code to convert them back but if you encounter errors it may be worth checking if any other odd characters have been inserted. One way to do this is print out what is being sent before it’s sent and then again in the .Net script after it’s been received. Then compare them. Thanks to primoz.cerar for helping me figure that out! (http://forums.coronalabs.com/topic/44141-mimeb64-encoding-uploading-file-error/)

 

web.config:  Make sure your web.config file has the maxRequestLength set to be larger than the maximum size you are likely to want to upload. The one I have set as default is 1GB which I would imagine would be ample.

 

Then upload the web.config and the receiveFile.aspx to the folder on your server that your LUA’s aspxPath variable is pointing to.

 

Note: make sure the folder you’re trying to save your file to on your server has write permissions or you won’t be able to save anything there.

 

Note 2: I’ve heard elsewhere on these forums that trying to upload to https currently doesn’t return regular progress events (so your progress bar won’t work). I haven’t tested this myself but it’s worth being aware of this if using https. I believe a bug report has been submitted to Corona.

 

Any questions, just respond below.

 

Thanks,

 

Ian

 

LUA - main.lua

local pb; local fileSize = 0; local aspxPath = "http://mySite.com/receiveFile.aspx"; local fileName = "track1.wav"; local uploadTimeout = 60; local widget = require("widget"); function init()     -- Add the upload button     addUploadButton(); end function addUploadButton()     local uploadButton = widget.newButton {         id = "u\_load",         label = "Upload File",         onEvent = btnUploadHandler     }     uploadButton.x = 240;     uploadButton.y = 80; end function btnUploadHandler( event )     if ("ended" == event.phase) then         uploadBinary ( fileName, aspxPath);     end end -- Upload file function uploadBinary ( filename, url )          local mime = require "mime";     local path = system.pathForFile( filename );          -- Open     local fileHandle = io.open( path, "rb" );     -- If we have a path to the file, upload file     if fileHandle then                  -- Encode the file         local fileEncoded = mime.b64( fileHandle:read( "\*a" ));                  -- Params (file, filename, progress and time out)         local params = {};         params.body = "fileBinary=" .. fileEncoded .. "&fileName="..filename;         params.progress = "upload";         params.timeout = uploadTimeout;                  -- Get the file size for progress bar         fileSize = string.len(fileEncoded);                  -- Set up the progress bar         pb = createProgressBar();                  -- Clean up         io.close( fileHandle );                  -- Make the POST         network.request( url, "POST", networkListener,  params);     end end function networkListener( event )     local phase = event.phase;     if (phase == "began") then print("BEGAN");     elseif (phase == "progress") then         -- Update the progress bar         pb.pbFill.width = (event.bytesTransferred / fileSize) \* 300;     elseif (phase == "ended") then         -- Set the progress bar to 100%         pb.pbFill.width = pb.width;         -- Add a message         addSuccessMessage();         -- Check if we encountered an error         if ( event.isError ) then             print( "Network error!")         else             print ( "RESPONSE: " ..event.response )         end     end end function createProgressBar()          local pbFill = display.newRect( 90, 160, 300, 30 );     pbFill.strokeWidth = 0;     pbFill:setFillColor( 1, 0, 0, 0.5 );     pbFill.width = 0;     pbFill.anchorX = 0;     pbFill.anchorY = 0.5;          local pb = display.newRect( 90, 160, 300, 30 );     pb.strokeWidth = 2;     pb:setFillColor( 0, 0, 0, 0 );     pb:setStrokeColor( 1, 1, 1 );     pb.anchorX = 0;     pb.anchorY = 0.5;          pb.pbFill = pbFill;     return pb; end function addSuccessMessage()     local msg = display.newText( "Upload Complete!", 0, 0, native.systemFont, 16 );     msg:setFillColor( 1, 0, 0 );     msg.anchorX = 0.5;     msg.anchorY = 0;     msg.x = 240;     msg.y = 190; end -- Call the init function init();  

ASP.Net - receiveFile.aspx

\<%@ Page Language="VB" ContentType="text/html" ResponseEncoding="utf-8" debug="true" &nbsp; %\> \<%@ Import Namespace="System.IO" %\> \<Script Runat="Server"\> &nbsp;&nbsp;&nbsp;&nbsp;'Dim str\_response As String &nbsp; &nbsp; sub Page\_Load(Source As Object, E As EventArgs) &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dim str\_FileName As String &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dim str\_FileBinary As String &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dim str\_savePath As String = "C:\inetpub\wwwroot\mySite\uploads\" &nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; str\_FileName = Request("fileName") &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str\_FileBinary = Request("fileBinary") &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;''''''''' Fix bug where all plus signs are being replaced with line breaks or spaces &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str\_FileBinary = str\_FileBinary.replace(vbcrlf, "+") &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str\_FileBinary = str\_FileBinary.replace(" ", "+") &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;''''''''' End fix bug &nbsp; &nbsp; &nbsp; &nbsp; If len(str\_FileBinary) \> 0 Then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Dim saveLocation As String = str\_savePath + str\_FileName &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dim b() As Byte = Convert.FromBase64String(str\_FileBinary) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If File.Exists(saveLocation) Then &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File.Delete(saveLocation) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End If &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;File.WriteAllBytes(saveLocation, b) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write("err=0") &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Else&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write("err=1")&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End if &nbsp; &nbsp; End Sub \</Script\>

web.config

\<!-- Web.Config Configuration File --\> \<configuration\> &nbsp; &nbsp; \<system.web\> &nbsp; &nbsp; &nbsp; &nbsp; \<customErrors mode="Off"/\> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<httpRuntime maxRequestLength="1048576" /\> &nbsp; &nbsp; \</system.web\> \</configuration\>

Enjoy!!

Thanks Ian! I have been trying to do this in ASP.NET for a while and couldn’t get it to work. I love the progress bar also. I did want to pass in a parameter in the URL so I was able to add something like ?id=123 at the end and then read it with the querystring in the code and works great.

Thanks again,

Warren

Thanks Ian! I have been trying to do this in ASP.NET for a while and couldn’t get it to work. I love the progress bar also. I did want to pass in a parameter in the URL so I was able to add something like ?id=123 at the end and then read it with the querystring in the code and works great.

Thanks again,

Warren

I have been using this routine with ASP.NET to upload pictures and has worked great. I now need to upload video files. If the files are not too big they upload fine. If they are large files the app gives a message it has stopped working. I have set the server to accept larger files but have not confirmed it is set right. How do I tell where the error is for these larger video files? I thought it was corona when copying the video file over before uploading but it gets past that. It could be the code in corona for uploading. Does the same code handle large files like 25mb?

Thanks,

Warren

Hi Warren,

I also had some problems with the server timing out on larger files.

What settings do you have in your web.config for allowing larger files / longer connection times…?

Thanks,

Ian

@ keystagefun

I’m having issues with the upload phase. I bought a Windows server-based site just so I could follow this process. however, I keep getting 101 errors. I set up a folder application on this server called ServiceAppDemo where I put the  receiveFile.aspx   I set up another folder called videotests to receive the videos.

I’m using this address inside the  receiveFile.aspx : Dim str_savePath As String = “G:\PleskVhosts\instacam.biz\httpdocs\videotests”

that address came from a test.asp file: <%= Server.MapPath("\videotests")%><br>

I also tried: Dim str_savePath As String =  Server.MapPath(“videotests”) and Dim str_savePath As String =  Server.MapPath("/videotests")  same error.

​any ideas would be terribly helpful! THANKS,keystagefun!

Hi there,

I’m not really a .Net expert, so my advice is going to be fairly limited, but the following thoughts spring to mind:

  • Does the folder on the server that you’re saving to (/videotests) have write permissions set to allow your script to save to it? If not then an error will occur. If your web space is on a shared server you may need to ask your web host or the server administrator to do this. Something along the lines of the below may help… http://www.techrepublic.com/blog/data-center/setting-basic-ntfs-permissions-in-windows-server-2012/

  • Are you seeing anything printed out in the console when the error occurs - the line print ( "RESPONSE: " …event.response ) is the line that should give you some more feedback. If nothing shows up there, have you tried accessing your script directly via a web browser and seeing if you receive an error in the browser with some more helpful information. You may need to set your web.config file to allow error messages to be displayed.

Thanks,

Ian

thanks for the quick and detailed response, Ian!

the best solution for my needs would be to be able to have the app send video directly to Camera Roll. Rob Miracle says Enterprise users like yourself should be able to. have you attempted this?

best,

Mike

I haven’t I’m afraid Mike. I’m sure if you ask on the forums somebody will have some info…

Is this after you’ve downloaded the video, you want it sent to the Camera Roll or after you’ve captured it, meaning you don’t need to upload it all?

These threads back up what you say about needing Enterprise to try it…

https://forums.coronalabs.com/topic/55832-save-a-downloaded-or-captured-video-to-the-camera-roll/

https://forums.coronalabs.com/topic/53635-save-captured-imagevideo-to-sub-folder-under-photolibrary/

Sorry I can’t be more help.

Cheers,

Ian

you’ve been plenty of help, Ian! thanks!

I have been using this routine with ASP.NET to upload pictures and has worked great. I now need to upload video files. If the files are not too big they upload fine. If they are large files the app gives a message it has stopped working. I have set the server to accept larger files but have not confirmed it is set right. How do I tell where the error is for these larger video files? I thought it was corona when copying the video file over before uploading but it gets past that. It could be the code in corona for uploading. Does the same code handle large files like 25mb?

Thanks,

Warren

Hi Warren,

I also had some problems with the server timing out on larger files.

What settings do you have in your web.config for allowing larger files / longer connection times…?

Thanks,

Ian

@ keystagefun

I’m having issues with the upload phase. I bought a Windows server-based site just so I could follow this process. however, I keep getting 101 errors. I set up a folder application on this server called ServiceAppDemo where I put the  receiveFile.aspx   I set up another folder called videotests to receive the videos.

I’m using this address inside the  receiveFile.aspx : Dim str_savePath As String = “G:\PleskVhosts\instacam.biz\httpdocs\videotests”

that address came from a test.asp file: <%= Server.MapPath("\videotests")%><br>

I also tried: Dim str_savePath As String =  Server.MapPath(“videotests”) and Dim str_savePath As String =  Server.MapPath("/videotests")  same error.

​any ideas would be terribly helpful! THANKS,keystagefun!

Hi there,

I’m not really a .Net expert, so my advice is going to be fairly limited, but the following thoughts spring to mind:

  • Does the folder on the server that you’re saving to (/videotests) have write permissions set to allow your script to save to it? If not then an error will occur. If your web space is on a shared server you may need to ask your web host or the server administrator to do this. Something along the lines of the below may help… http://www.techrepublic.com/blog/data-center/setting-basic-ntfs-permissions-in-windows-server-2012/

  • Are you seeing anything printed out in the console when the error occurs - the line print ( "RESPONSE: " …event.response ) is the line that should give you some more feedback. If nothing shows up there, have you tried accessing your script directly via a web browser and seeing if you receive an error in the browser with some more helpful information. You may need to set your web.config file to allow error messages to be displayed.

Thanks,

Ian

thanks for the quick and detailed response, Ian!

the best solution for my needs would be to be able to have the app send video directly to Camera Roll. Rob Miracle says Enterprise users like yourself should be able to. have you attempted this?

best,

Mike

I haven’t I’m afraid Mike. I’m sure if you ask on the forums somebody will have some info…

Is this after you’ve downloaded the video, you want it sent to the Camera Roll or after you’ve captured it, meaning you don’t need to upload it all?

These threads back up what you say about needing Enterprise to try it…

https://forums.coronalabs.com/topic/55832-save-a-downloaded-or-captured-video-to-the-camera-roll/

https://forums.coronalabs.com/topic/53635-save-captured-imagevideo-to-sub-folder-under-photolibrary/

Sorry I can’t be more help.

Cheers,

Ian

you’ve been plenty of help, Ian! thanks!