This article will explain how to upload large files from Android client to an ASP.NET server.
We are going to implement several methods on Android and ASP.NET, and take a look at some ASP.NET server configurations.
First we are going to implement a simple Java class with enum which identifies the http request errors.
This is not necessary, but it will make it much easier to handle the problems on the UI, which accrue while sending the http request.
We are going to get the HttpResult as a response from our method and we’ll be able to understand not only if the message was sent, but also what exception stopped the execution.
public enum HttpErrors
{
NO_ERROR,
ConnectTimeoutException,
SocketTimeoutException,
ClientProtocolException,
IOException
}
public class HttpResult
{
public HttpErrors Error;
public String Result;
public HttpResult(String serverMessage, HttpErrors error)
{
Result = serverMessage;
Error = error;
}
public boolean IsError()
{
return !Error.equals(HttpErrors.NO_ERROR);
}
}
This method simply forms the URL. Well, not in this example but if you need to set some GET parameters in it, this is the place.
It identifies whether the file exist or not, and accordingly to the file size, sets the timeout of the Request by passing double value to PostFile method.
public HttpResult SendFile(File file)
{
String url = "your_server_url";
if(file.exists())
{
double timeout = file.length() / 1024 / 20;
result = PostFile(file, url, (int)timeout);
}
return result;
}
This method is the one that sends the given file to the specified server by URL using POST method.
It’s based on the use of HttpClient , HttpPost and FileEntity SDK classes.
It initiates our httpClient object and HttpPost. Afterwards it sets the FileEntitys ContentType to “application/zip” and setting it as the entity of the request.
In the try-catch we are waiting for server response and setting it as String type to our result.
If the execution time of the request is more than our specified timeout, SocketTimeoutException exception will be thrown.
Remember that any network communication cannot be on the main Thread!
public HttpResult PostFile(File file, String url, int timeout)
{
HttpResult result = null;
HttpClient httpclient = new DefaultHttpClient();
HttpPost request = new HttpPost(url);
request.setParams(GetHttpParams(timeout));
FileEntity reqEntity = new FileEntity(file, "application/zip");
request.setEntity(reqEntity);
HttpResponse response;
try
{
response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null)
{
result = new HttpResult(EntityUtils.toString(entity),
HttpErrors.NO_ERROR);
entity.consumeContent();
}
}
catch(SocketTimeoutException timeout)
{
result = new HttpResult(null,HttpErrors.SocketTimeoutException);
}
catch (ClientProtocolException e)
{
result = new HttpResult(null, HttpErrors.ClientProtocolException);
}
catch (IOException e)
{
result = new HttpResult(HttpErrors.IOException);
}
httpclient.getConnectionManager().shutdown();
return result;
}
That’s all we need on the client (Android) side, those methods cover all your needs of sending large files to the server.
On the server side, you need to implement this method as you are accessing the page.
This method will read the input stream bytes in the client request, and saves the file by calling the Save() method.
Additional data may be set as parameters in the URL query string. Anyway, this is just a suggestion.
private void Handlefile()
{
int length = (int)Request.InputStream.Length;
byte[] buffer = new byte[length];
Request.InputStream.Read(buffer, 0, length);
Save(buffer);
}
Example for a Save method:
void Save(byte[] bytes)
{
System.IO.File.WriteAllBytes("C:\MyServerData\new_file.bin", bytes);
}
Web.config file is a configuration file in xml format. It specifies configurations for your ASP application.
Those configurations can be set in this file or set programmatically.
One important advantage of this file is that you can change your program settings without touching your compiled code on the server.
For example, when debugging your application, usually you will want to get errors from the server. That can be accomplished by specifying:
<configuration>
<system.web>
<customErrors mode="On"/>
</system.web>
</configuration>
After your code is compiled and set on the IIS you can change its mode value as you wish.
In our case, we need to specify other parameters.
We are going to specify httpRuntime node under the system.web node.
</system.web>
<httpRuntime maxRequestLength="102400" executionTimeout="3600" />
</system.web>
Here we are specifying the maximum length of the files (in our case its set to 100MB) and execution time of the request (in our case, 1 hour).
Another requirement is:
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="104857600" />
</requestFiltering>
</security>
Which specifies the maximum value of the Http request limit (in our case is set to 100MB).
We implemented both client and server sides in this article. Once it is set on your application you will not be concerned again about file transportation from android to ASP.
My code examples were simplified intentionally, since it depends on your program, and when and where you decide to use them.