如何使用Progress Bar在ASP.NET MVC(C#)中异步上载多个文件

时间:2016-06-22 20:53:03

标签: c# asp.net asp.net-mvc asp.net-mvc-4 asynchronous

我正在构建一个基于MVC的ASP.NET应用程序。其中一项功能应该是能够使用进度条异步上传文件。

我已成功上传没有进度条的文件。下面的代码就是这样。

查看代码:

<input class="file" type="file" name="file" id="file" />
<input type="submit" name="submit" value="Upload" />

控制器代码:

    public ActionResult Upload(){
        return View();
    }

    [HttpPost]
    public ActionResult Upload(Resource resource)
    {
        try
        {
            if (resource.File.ContentLength > 0)
            {
                var fileName = Path.GetFileName(resource.File.FileName);
                var path = Path.Combine(Server.MapPath("~/Content/Resources"), fileName);
                resource.File.SaveAs(path);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("Cannot upload file. Exception of type : {0}", e.ToString());
        }
        return RedirectToAction("Upload");
    }

这段代码非常好用。稍作修改,我甚至可以上传多个文件。但是,即使我已经尝试找到它,我也无法使用进度条上传文件。

感谢任何帮助。

2 个答案:

答案 0 :(得分:3)

我就是这样做的 - 控制器代码大致相同,但是客户端有一些javascript来监控和更新ajax发布的进度。 UI Html是这样的:

    <div id="uploadDetails" class="form-group">
        <div class="input-group">
            <span class="input-group-btn">
                <span class="btn btn-primary btn-file">
                    Browse&hellip; <input type="file" name="file" id="file" />
                </span>
            </span>
            <input type="text" id="filename" class="form-control fullwidth" readonly />
            <span class="input-group-btn">
                <button class="btn btn-primary" type="button" id="uploadFile"><span class="glyphicon glyphicon-upload"></span> Upload File </button>
            </span>
        </div>
    </div>

上传的javascript如下:

    $(document).on('click', '#uploadFile', function (e) {
        var fileElement = document.getElementById('file');
        var file = fileElement.files[0];

        var formData = new FormData();
        formData.append("filename", fileElement.files[0].name);
        formData.append("id", '@Model.SharedIP.Id');
        formData.append("file", file, fileElement.files[0].name);

        var html = $('#uploadFile').html();
        $('#uploadFile').html('Uploading...');

        $.ajax({
            url: "@Url.Action("UploadFile", "SharedIP")",
            type: "POST",
            data: formData,
            processData: false,  // tell jQuery not to process the data
            contentType: false,   // tell jQuery not to set contentType
            xhr: function(){
                var xhr = new window.XMLHttpRequest();
                xhr.upload.addEventListener("progress", function(evt){
                    if (evt.lengthComputable) {
                        $('#uploadFile').html('Uploading... ' + Math.round((evt.loaded / evt.total) * 100) + '%');
                    }
                    else $('#uploadFile').html('hmmm');
                }, false);
                return xhr;             
            },
            success: function (results) {
                updateFilesList();
                $('#uploadFile').html(html);
                fileElement.files = [];
                var control = $('#file');
                control.replaceWith(control.clone(false));
                $('#filename').val("")
            },
            error: function (xhr, ajaxOptions, thrownError) {  
                $('#uploadFile').html(html);
                alert(xhr.responseText);  
            }  

        });
    });

为了完整性,这里是Controller签名,它的.net Core RC1可能不适用于您的目标框架,但您会明白这一点。

    [HttpPost]
    public IActionResult UploadFile(string filename, Guid id, IFormFile file)
    {
        IPFile ipfile = new IPFile()
        {
            ContentType = file.ContentType,
            DateUploaded = DateTime.Now,
            Filename = filename,
            SharedIPId = (id == Guid.Empty ? (Guid?)null : id), 
            Id = Guid.NewGuid(),
            UploadedBy = User.Alias(),
        };

        ipfile = FileManager.AddFileFromStream(User.Alias(), ipfile, file.OpenReadStream());

        return Ok(ipfile);
    }

希望能回答你的问题。

[编辑]刚刚意识到这不是一个进步条&#34; - 但它有所有的工作方式和%显示 - 要设置进度条,你只需将CSS应用于以图形方式呈现%的元素 - 请参阅http://www.w3schools.com/bootstrap/bootstrap_progressbars.asp之类的帖子实例

答案 1 :(得分:1)

这是我尝试过的代码。它只是一个最低限度的代码,但按预期工作。它仍然有一些错误,如果有人能让它免于bug,我将不胜感激。

一些错误:

  1. 进度条不会在新文件上传时重置。
  2. 添加按钮进行上传(我也可以自己动手)。
  3. 型号代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace NewDeploymentsTesting.Models
    {
        public class UploadFilesResult
        {
            public string Name { get; set; }
            public int Length { get; set; }
            public string Type { get; set; }
        }
    }
    

    控制器代码:

    using NewDeploymentsTesting.Models;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    
    namespace NewDeploymentsTesting.Controllers
    {
        public class HomeController : Controller
        {
            // GET: Home
            public ActionResult Index()
            {
                return View();
            }
    
            [HttpPost]
            public ContentResult UploadFiles()
            {
                var r = new List<UploadFilesResult>();
                foreach (string file in Request.Files)
                {
                    HttpPostedFileBase hpf = Request.Files[file] as HttpPostedFileBase;
                    if (hpf.ContentLength == 0) continue;
                    string savedFileName = Path.Combine(Server.MapPath("~/Content/Resource"), Path.GetFileName(hpf.FileName));
                    hpf.SaveAs(savedFileName);
                    r.Add(new UploadFilesResult()
                    {
                        Name = hpf.FileName,
                        Length = hpf.ContentLength,
                        Type = hpf.ContentType
                    });
                }
                return Content("{\"name\":\"" + r[0].Name + "\",\"type\":\"" + r[0].Type + "\",\"size\":\"" + string.Format("{0} bytes", r[0].Length) + "\"}", "application/json");
            }
        }
    }
    

    查看代码:

    @{Layout = null;}
    
    <!DOCTYPE html>
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>Uploading Files</title>
        <link href="~/Content/bootstrap/bootstrap.min.css" rel="stylesheet" />
        <link href="~/Content/bootstrap/bootstrap-theme.css" rel="stylesheet" />
        <link href="~/Content/jquery.fileupload.css" rel="stylesheet" />
        <script src="~/Scripts/jquery-1.9.1.min.js"></script>
        <script src="~/Scripts/jquery.ui.widget.js"></script>
        <script src="~/Scripts/bootstrap.min.js"></script>
        <script src="~/Scripts/jquery.fileupload.js"></script>
    
        <script type="text/javascript">
            $(document).ready(function () {
                $('#fileupload').fileupload({
                    dataType: 'json',
                    url: '/Home/UploadFiles',
                    autoUpload: true,
                    done: function (e, data) {
                        $('.file_name').html(data.result.name);
                        $('.file_type').html(data.result.type);
                        $('.file_size').html(data.result.size);
                    }
                }).on('fileuploadprogressall', function (e, data) {
                    var progress = parseInt(data.loaded / data.total * 100, 10);
                    $('.progress .progress-bar').css('width', progress + '%');
                });
            });
        </script>
    </head>
    <body>
        <div class="container">
            <span class="btn btn-success fileinput-button">
                <i class="glyphicon glyphicon-plus"></i>
                <span>Add Files ...</span>
                <input id="fileupload" type="file" name="files[]" multiple />
            </span><br />
            <div class="progress">
                <div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%;">
                    <span class="sr-only">0% Complete</span>
                </div>
            </div><br />
            <div class="file_name"></div><br />
            <div class="file_type"></div><br />
            <div class="file_size"></div><br />
        </div>
    </body>
    </html>
    

    以下是浏览器窗口中的内容。

    Before uploading a file.

    After uploading the file