ajax xhr导致mvc控制器异步

时间:2018-06-20 08:55:54

标签: jquery ajax asp.net-mvc file-upload

您好,我有一个音频文件上传问题。当用户上传一个或多个文件时,我将显示一个文件上传对话框,其中包含总上传的进度(百分比)。问题是我的控制器正在一次(异步)处理所有文件,导致仅其中一个文件将被添加到我的列表中。在调试时,代码会跳来跳去,并且值也会更改。 如果我在上载方法中将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);
            }
        });
    }

0 个答案:

没有答案