Asp.net MVC异步上传问题

时间:2016-03-12 08:42:42

标签: c# asp.net asp.net-mvc file-upload

我们正在进行文件上传,并选择了blueimp插件。我们通过以下方式开展此工作。

用户选择他们想要上传的所有文件,然后点击一个按钮一次上传所有文件。

这部分工作正常,一次将所有文件发送到服务器。

服务器代码示例仅如下所示。

public async Task<ActionResult> Upload()
{
    var result = await new Uploader().UploadFile(Request.Files[0]);
    return Json(result);
}
public class Uploader
{
    public async Task<UploadResult> UploadFile(HttpPostedFileBase file)
    {
        //do file processing and save file to disk
        var filerecord = _fileService.GetById(xxxx);
        filerecord.files.Add(new Info { name = file.FileName, size = file.ContentLength });
        //Here for us its Mongo but any not sure what the result would be against another db
        await _fileService.SaveAsync(filerecord);
        return new UploadResult { message = "ok" };
    }
}

//js
    fi.fileupload({
        url: 'uploadfile',
        dataType: 'json',
        autoUpload: false,
        singleFileUploads:false,
        maxNumberOfFiles: maxFiles,
        acceptFileTypes: /(\.|\/)(jpe?g)$/i,
        maxFileSize: 1048576*2, //1MB
        messages: { },
        // Enable image resizing, except for Android and Opera,
        // which actually support image resizing, but fail to
        // send Blob objects via XHR requests:
        disableImageResize: true,
        previewMaxWidth: 50,
        previewMaxHeight: 50,
        previewCrop: false,
        dropZone: $('#dropzone')
    });

    fi.on('fileuploadadd', function (e, data) {

        $('form').submit(function (e) {
            data.submit();
            return false;
        });
});

请注意,在这种情况下,数据库是Mongo

问题 一次上传单个文件,即选择文件点击上传,所有工作都按预期工作。 选择多个文件并点击上传按钮将所有文件上传并保存到磁盘而不会出现问题。但是我希望以下行为

  1. 从db获取记录
  2. 添加有关文件的信息
  3. 保存记录
  4. 如前所述,这对于一次只有一个文件非常有效,但是当它们全部进入时,我猜测异步行为会导致该方法失去其工作的文件的上下文,因为调试器中的3个步骤似乎是随机调用每个文件而不是按顺序调用。

    我尝试了各种方法,比如改变事情发生的顺序,也使用了ConfigureAwait等。

    任何建议都将受到赞赏。

1 个答案:

答案 0 :(得分:0)

如果我理解你的情况,这段代码应该适合你:

public async Task<ActionResult> Upload()
{
    var files = new HttpPostedFileBase[Request.Files.Count];
    Request.Files.CopyTo(files, 0);
    var tasks = files.Select(f=>new Uploader().UploadFile(f));
    await Task.WhenAll(tasks);
    return Json(tasks.Where(v=>v.Status == TaskStatus.RanToCompletion ).Select(v=>v.Result).ToList());
}