您好,我有一个音频文件上传问题。当用户上传一个或多个文件时,我将显示一个文件上传对话框,其中包含总上传的进度(百分比)。问题是我的控制器正在一次(异步)处理所有文件,导致仅其中一个文件将被添加到我的列表中。在调试时,代码会跳来跳去,并且值也会更改。 如果我在上载方法中将async设置为false,则将无法获得每个文件的进度。 奇怪的是,如果在上传单个或多个文件之后上传多个文件,则不会发生错误。
控制器:
[HttpPost]
public ActionResult UploadAudioFile(HttpPostedFileBase file, int? timestamp)
{
if (file == null || timestamp == null) return Json(new { isSuccess = false });
var supportedFileTypes = new[] { "audio/mp3", "audio/wav", "audio/mpeg" };
int hh = 0, mm = 0, ss = 0, ms = 0, id = 0;
int errorCount = 0;
var errorMsg = "";
MusicViewModel song = null;
StreamViewModel streams = new StreamViewModel()
{
StreamList = new List<StreamChildViewModel>()
};
if (TempData[TEMP_SESSIONSTREAMS] != null)
{
streams.StreamList = (List<StreamChildViewModel>)TempData[TEMP_SESSIONSTREAMS];
}
var base64 = "";
var contentType = file.ContentType.ToLower();
if (!supportedFileTypes.Contains(contentType))
{
errorCount++;
}
else
{
var s = file.InputStream;
var name = file.FileName;
try
{
song = _musicRepo.GetMetaDataFromMp3File(s, name);
if (song != null)
{
streams.StreamList = _musicRepo.AddSongToPlayList(streams.StreamList, s,
file.ContentLength, contentType, song.Duration, (int)timestamp);
byte[] b = streams.StreamList.Last().ByteArr;
id = streams.StreamList.Last().Id;
//Stream stream = new MemoryStream(b);
//ReadBytesToString(stream);
base64 = Convert.ToBase64String(b);
}
}
catch (OutOfMemoryException)
{
return Json(new { isSuccess = false, errorMsg = "You have attempted to upload a file that is too big. " });
}
catch (Exception ex)
{
return Json(new { isSuccess = false, errorMsg = ex.Message });
}
}
TempData[TEMP_SESSIONSTREAMS] = streams.StreamList;
TempData.Keep(TEMP_SESSIONSTREAMS);
if (Request.Files.Count == errorCount)
{
return Json(new { isSuccess = false, errorMsg = "We only allow audio files of .mp3 or .wav format and all your files doesn't match those." });
}
else if (song != null)
{
var obj = new
{
isSuccess = true,
ContentType = contentType,
AudioFile = base64,
Song = song,
Id = id,
ErrorMsg = errorMsg,
ErrorCount = errorCount
};
var serializer = new JavaScriptSerializer();
serializer.MaxJsonLength = Int32.MaxValue;
var result = new ContentResult()
{
Content = serializer.Serialize(obj),
ContentType = "application/json"
};
return result;
}
return Json(new { isSuccess = false });
}
js中的onchange方法
$('input#import-music-child_file-upload-deskopt').on('change', function (e) {
e.preventDefault(); // stop the standard form submission
var $file = document.getElementById('import-music-child_file-upload-deskopt');
startFileUpload($file.files.length);
fileUpload_arr = [];
fileUpload_tr_counter = 0;
fileUpload_files_counter = $file.files.length;
var tr = $('table#music_details_table tbody tr');
var timeStampArr = [];
if ($file.files.length > 0) {
var size = 0, totalSize = 0;
for (var j = 0; j < $file.files.length; j++) {
size = $file.files[j].size;
totalSize = size + totalSize;
var obj = {
index: j,
loaded: 0,
size: size,
isLoadComplete: false
}
fileUpload_arr.push(obj);
}
size = 0;
var widthUntill = 0;
for (var i = 0; i < $file.files.length; i++) {
widthUntill = widthUntill + size;
size = $file.files[i].size;
var x = Math.floor(Math.log(size) / Math.log(1024));
var humanSize = (size / Math.pow(1024, x)).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][x];
addUploadFileToUploadDialog($file.files[i].name, humanSize);
var ts = moment().unix();
if (timeStampArr.length > 0) {
var res = $.grep(timeStampArr, function (n, h) {
if (n === ts) return n;
});
if (res.length >= 1) {
ts = ts + timeStampArr.length;
}
timeStampArr.push(ts);
}
else
timeStampArr.push(ts);
var tableIndex = tr + j;
$.when(addAudioFiles($file.files[i], i, size, widthUntill, totalSize, ts, tableIndex)).done(function (x) {
});
}
}
$('ul#import-music_btn').removeClass('open');
});
将数据发送到控制器的jQuery方法:
function addAudioFiles(file, index, fileSize, widthUntillNow, uploadSize, timestamp, musicTableIndex) {
if (file == null) return null;
var $formData = new FormData();
//$formData.append(name, file);
$formData.append('file', file);
$formData.append('timestamp', timestamp);
var dg = $('div#sd_fileUpload_progress');
var percentageBar = dg.find('p#sd_fileUpload_progress_percentage');
$.ajax({
url: '/SessionDesigner/UploadAudioFile',
type: 'POST',
data: $formData,
//dataType: 'json',
cache: true,
contentType: false,
processData: false,
xhr: function () {
console.log('xhr');
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function (evt) {
console.log('t');
if (evt.lengthComputable) {
var upload = 0, loaded = 0;
for (var j = 0; j < fileUpload_arr.length; j++) {
if (j === index) {
if (fileUpload_arr[j].isLoadComplete === false) {
if (fileUpload_arr[j].size <= evt.loaded) {
fileUpload_arr[j].isLoadComplete = true;
fileUpload_arr[j].loaded = fileUpload_arr[j].size;
upload = 0;
}
else if (fileUpload_arr[j].loaded + evt.loaded < fileUpload_arr[j].size) {
fileUpload_arr[j].loaded = fileUpload_arr[j].loaded + evt.loaded;
}
}
else {
upload = 0;
}
fileUpload_arr[j].loaded = fileUpload_arr[j].loaded + upload;
}
loaded = fileUpload_arr[j].loaded + loaded;
}
if (loaded <= uploadSize) {
var percent = Math.floor((loaded / uploadSize) * 100);
percentageBar.text(percent + ' %');
console.log('p ' + percent);
if (percent === 100) {
stopFileUpload();
}
}
}
else {
console.log('error xhr');
}
}, false);
return xhr;
},
success: function (data) {
console.log('success');
if (data.isSuccess === true) {
//..Stuff
}
else {
//..Stuff
}
},
error: function (xhr, error, status) {
console.log(error, status);
}
});
}