Consider the following code example:

var fileName = "~stacktrace & stuff.txt";
var content = new MultipartFormDataContent();

var fileStream = new FileStream(String.Format(@"/mnt/sdcard/Download/{0}",
fileName), FileMode.Open, FileAccess.Read);

content.Add(new StreamContent(fileStream), "contentFile", fileName);

Notice the fileName: "~stacktrace & stuff.txt".

When attempting to execute this code, you may receive an IndexOutOfRangeException or an Invalid format error. The problem appears to be that the platform-specific Mono implementation of HttpClient does not wrap the file name in quotation marks when posting the payload. Data (e.g. - file name) with spaces and special characters won't post.

It's a bug

The problem has been filed on Bugzilla, and appears to be a bug in the platform-specific implementations of Mono HttpClient.

The Workaround

Now, try this:

var fileName = "~stacktrace & stuff.txt";
var content = new MultipartFormDataContent();

var fileStream = new FileStream(String.Format(@"/mnt/sdcard/Download/{0}", fileName), FileMode.Open, FileAccess.Read);

var streamContent = new StreamContent(fileStream);

streamContent.Headers.ContentDisposition = ContentDispositionHeaderValue.Parse("form-data");

streamContent.Headers.ContentDisposition.Parameters.Add(new NameValueHeaderValue("name", "contentFile"));

streamContent.Headers.ContentDisposition.Parameters.Add(new NameValueHeaderValue("filename", "\"" + fileName + "\""));

content.Add(streamContent);

The difference is that in this case we are setting the content headers directly rather than letting the inner-workings of HttpClient work them out. By doing so, we can ensure that the file name is wrapped in quotation marks -- allowing the values to post as expected.

Thanks to Derek Beattie for his notes on this Xamarin forum post.