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.