繁体   English   中英

如何使用进度条在ASP.NET MVC(C#)中异步上传多个文件

[英]How to upload multiple files asynchronously in ASP.NET MVC (C#) using Progress Bar

我正在构建一个基于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");
    }

此代码绝对可以正常工作。 稍作修改,我什至可以上传多个文件。 但是,即使我尝试找到它,也无法使用进度条上传文件。

任何帮助表示赞赏。

这就是我的操作方式-控制器代码基本相同,但是客户端中包含一些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);
    }

希望这能回答你的问题。

[编辑]刚刚意识到这不是一个“进度条”-但是它具有所有工作原理和%显示-要放置进度条,您只需将CSS应用于将图形化为%呈现的元素-参见例如http://www.w3schools.com/bootstrap/bootstrap_progressbars.asp之类的帖子。

这是我尝试过的代码。 这是最低限度的代码,但可以正常工作。 它仍然有一些错误,如果有人可以使其没有错误,我将不胜感激。

一些错误:

  1. 进度栏不会在新文件上传时重置。
  2. 添加一个按钮进行上传(我也可以自己完成)。

型号代码

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>

这是浏览器窗口中的外观。

上传文件之前。

上传文件后

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM