Upload Files from Windows Phone
Posted on August 19, 2011 by Chris Koenig
When speaking to a crowd of Windows Phone developers the other day, I was asked an interesting question about uploading files. We talk about how, with Mango, you can use the BackgroundAgents to download tons of data to the device, but we never talk about uploading. As I understand it (at least as of this writing) although uploads are limited to 5MB, there are no good samples out there on *how* to upload them. Sure, I can use the built-in Facebook or Skydrive sharing features, but where's the fun in that? What if I want to be able to post to my *own* repository? This post is my attempt to answer that question – it’s as much for me to remember how I did it as it will hopefully be helpful to you to see how I accomplished it.
To make it more interesting, I decided that I would implement the server as an MVC application, and only accept REST-based POST actions through a FileController (that’s for you, Amir).
So, here’s the code – I hope you enjoy it!
Here’s my Controller (FileController.cs)
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.Mvc;
namespace MvcApplication1.Controllers
{
public class FileController : Controller
{
[HttpPost]
public ActionResult Upload()
{
string filename = Server.MapPath("/Uploads/" + Path.GetRandomFileName();
try
{
using (FileStream fs = new FileStream(filename), FileMode.Create))
{
using (BinaryWriter bw = new BinaryWriter(fs))
{
using (BinaryReader br = new BinaryReader(Request.InputStream))
{
long bCount = 0;
long fileSize = br.BaseStream.Length;
const int BLOCK_SIZE = 4096;
byte[] bytes = new byte[BLOCK_SIZE];
do
{
bytes = br.ReadBytes(BLOCK_SIZE);
bCount += bytes.Length;
bw.Write(bytes);
} while (bCount < fileSize);
}
}
}
return Json(new { Result = "Complete" });
}
catch (Exception ex)
{
return Json(new { Result = "Error", Message = ex.Message });
}
}
}
}
And here's my MainPage.xaml.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Tasks;
namespace PhoneApp10
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
}
private void SelectButton_Click(object sender, RoutedEventArgs e)
{
PhotoChooserTask task = new PhotoChooserTask();
task.Completed += task_Completed;
task.Show();
}
private void task_Completed(object sender, PhotoResult e)
{
if (e.TaskResult != TaskResult.OK)
return;
const int BLOCK_SIZE = 4096;
Uri uri = new Uri("http://localhost:4223/File/Upload", UriKind.Absolute);
WebClient wc = new WebClient();
wc.AllowReadStreamBuffering = true;
wc.AllowWriteStreamBuffering = true;
// what to do when write stream is open
wc.OpenWriteCompleted += (s, args) =>
{
using (BinaryReader br = new BinaryReader(e.ChosenPhoto))
{
using (BinaryWriter bw = new BinaryWriter(args.Result))
{
long bCount = 0;
long fileSize = e.ChosenPhoto.Length;
byte[] bytes = new byte[BLOCK_SIZE];
do
{
bytes = br.ReadBytes(BLOCK_SIZE);
bCount += bytes.Length;
bw.Write(bytes);
} while (bCount < fileSize);
}
}
};
// what to do when writing is complete
wc.WriteStreamClosed += (s, args) =>
{
MessageBox.Show("Send Complete");
};
// Write to the WebClient
wc.OpenWriteAsync(uri, "POST");
}
}
}
I wrote this using the latest tools available at the time - which is the Windows Phone SDK 7.1 Beta 2 Refresh, so YMMV depending on which version of the tools you're using. I am hopeful that one day I'll be able to look back at this post and laugh at how much code it took to do this simple file upload...
Comments (7)








after we have uploaded the image how can we get data from the server or a website?
I’m trying to do this via VB.Net-code. Could you help me, please?
I’m trying to upload an audio file to a php script. How can I do this?
hi,
how should i add using System.Web.Mvc in FileController.cs.? IS there any apeciall dll to be added.?
Hi Chris,
bw.Write(bytes) keeps increasing memory usage, even when setting AllowWriteStreamBuffering=false. So still limited to some file sizes depending on available memory. Ie, you cannot upload a 5mb file if available memory for the app is 5mb or less. It gets even worse when you try to upload from inside a Scheduled Task where memory cap is 5mb…
I have also tried with HttpWebRequest, its so frustrating…
Thank you for your email! I am currently out of the office attending South by Southwest Interactive in Austin. If your need is urgent, please call my cell phone below. Otherwise, I will return your email just as soon as I can.
Thanks!
Chris
Chris Koenig | +1 (214) 385-5616 | Developer Evangelist
blog: http://chriskoenig.net/ | twitter: @chriskoenig
Excuse me
I am s student , and start learning window phone
Could you share your file to me?
Because I cannot find my file which I uploaded.