There seems to be an issue with deserializing the data sent using the multipart/form-data type within an MVC 5 project. Despite appearing valid in Fiddler, the data is not being mapped into the controller method. While debugging, it is evident that all parameters are null.
The form sends one hidden text field and up to two files to the controller. Below is the method signature:
[HttpPost]
public async Task<ActionResult> UploadFile(string id, FormCollection form, IEnumerable<HttpPostedFileBase> files)
The implementation of the method is irrelevant as the problem lies in the parameters not being populated.
Here is a redacted version of the Fiddler output:
POST http://localhost:52876/Projects/UploadFile/5550cdc52300560f6c7b36eb HTTP/1.1
Host: localhost:52876
Connection: keep-alive
Content-Length: 90889
Authorization: Negotiate oXcwdaADCgEBoloEWE5UTE1TU1AAAwAAAAAAAABYAAAAAAAAAFgAAAAAAAAAWAAAAAAAAABYAAAAAAAAAFgAAAAAAAAAWAAAABXCiOIGAbEdAAAADwAbnJriMKEzkS3OifgoahejEgQQAQAAAPUXp1AtIpqEAAAAAA==
Accept: */*
Origin: http://localhost:52876
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36
Content-Type: multipart/form-data
DNT: 1
Referer: http://localhost:52876/Projects/ProjectSetupForm/5550cdc52300560f6c7b36eb
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: donotshowgettingstarted=%7B%22state%22%3Atrue%7D; __RequestVerificationToken=UnL5s7w5OYKgywE5L8jqwbH8PulgF0BG0Ne_qZV5QMOj7pWdXw6qzN1pRYqc4rwKYiWveltrBs1SmJe2o7ndXufkOJFrC1wHOoK2zAXdnQw1
------WebKitFormBoundaryB3sb0uQDOIiNQXCD
Content-Disposition: form-data; name="__RequestVerificationToken"
f25ipWgwweX4S9Y6aEnQdxGCsvr7D3RznTui8_b5paCT1uTV8UNG0d6zJDXKUWYPHISOKmgD24KH206x_PGQ3KpXlG9YgOL-qqJ8v7DPETVfGk2PvsFm2aKuAS3xAYZI0
------WebKitFormBoundaryB3sb0uQDOIiNQXCD
Content-Disposition: form-data; name="files"; filename="MyIcon.bmp"
Content-Type: image/bmp
[REDACTED FILE CONTENTS]
------WebKitFormBoundaryB3sb0uQDOIiNQXCD
Content-Disposition: form-data; name="files"; filename=""
Content-Type: application/octet-stream
------WebKitFormBoundaryB3sb0uQDOIiNQXCD
Content-Disposition: form-data; name="type"
output
------WebKitFormBoundaryB3sb0uQDOIiNQXCD--
The debugging data shows only one file being sent and a blank file field. The same results occur when both fields are populated.
Below is the JavaScript method handling the form onSubmit event:
$('#attachment-upload form').submit(function (e) {
e.preventDefault();
$('#attachment-upload').removeClass('fade').modal('hide');
$('#attachment-progress').modal('show').addClass('fade');
$.ajax({
xhr: function () {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener('progress', function (event) {
if (event.lengthComputable) {
var percent = (event.loaded / event.total) * 100;
$('#attachment-progress div.modal-body .progress-bar').width(percent);
$('#attachment-progress div.modal-body .progress-bar').attr('aria-valuenow', percent);
$('#attachment-progress div.modal-body .progress-bar span').html(percent);
}
}, false);
return xhr;
},
url: this.action,
type: 'POST',
contentType: "multipart/form-data",
processData: false,
data: new FormData(this),
success: function (data) {
//my success function here
},
error: function (jqxhr, status, error) {
$('#upload-progress-section').addClass('hidden');
$('#upload-complete-section').removeClass('hidden');
$('#attachment-progress div.modal-header h1').html("Upload Error");
$('#upload-complete-section p').html("Upload has failed: " + status + " - " + error);
$('#attachment-progress div.modal-footer button').removeAttr('disabled');
}
});
});
Based on the Fiddler output, it seems like there might be an issue with the controller method signature, causing parameter binding failure. It is surprising that even the FormCollection parameter is null.
Are there any known issues with using multipart/form-data to upload files via ajax, or could there be a mistake in the implementation?