zoukankan      html  css  js  c++  java
  • ASP.NET Core文件上传与下载(多种上传方式)

    前言

    前段时间项目上线,实在太忙,最近终于开始可以研究研究ASP.NET Core了.

    打算写个系列,但是还没想好目录,今天先来一篇,后面在整理吧.

    ASP.NET Core 2.0 发展到现在,已经很成熟了.下个项目争取使用吧.

    正文

    1.使用模型绑定上传文件(官方例子)

    官方机器翻译的地址:https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads

    这里吐槽一下 - -,这TM的机器翻译..还不如自己看E文的..

    首先我们需要创建一个form表单如下:

        <form method="post" enctype="multipart/form-data" asp-controller="UpLoadFile" asp-action="FileSave">
            <div>
                <div>
                    <p>Form表单多个上传文件:</p>
                    <input type="file" name="files" multiple />
                    <input type="submit" value="上传" />
                </div>
            </div>
        </form>

    其中,asp-controllerasp-action,(这个是TagHelper的玩法,以后讲)是我们要访问的控制器和方法.

    给我们的input标签加上 multiple 属性,来支持多文件上传.

    创建一个控制器,我们编写上传方法如下:

     public async Task<IActionResult> FileSave(List<IFormFile> files)
            {
                var files = Request.Form.Files;
                long size = files.Sum(f => f.Length);
                string webRootPath = _hostingEnvironment.WebRootPath;
                string contentRootPath = _hostingEnvironment.ContentRootPath;
                foreach (var formFile in files)
                {
                    if (formFile.Length > 0)
                    {
    
                        string fileExt = GetFileExt(formFile.FileName); //文件扩展名,不含“.”
                        long fileSize = formFile.Length; //获得文件大小,以字节为单位
                        string newFileName = System.Guid.NewGuid().ToString() + "." + fileExt; //随机生成新的文件名
                        var filePath = webRootPath +"/upload/" + newFileName;
                        using (var stream = new FileStream(filePath, FileMode.Create))
                        {
                            
                            await formFile.CopyToAsync(stream);
                        }
                    }
                }
    
                return Ok(new { count = files.Count, size });
            }

    这里我们采用Asp.NET Core的新接口IFormFile,  IFormFile的具体定义如下:

    public interface IFormFile
    {
        string ContentType { get; }
        string ContentDisposition { get; }
        IHeaderDictionary Headers { get; }
        long Length { get; }
        string Name { get; }
        string FileName { get; }
        Stream OpenReadStream();
        void CopyTo(Stream target);
        Task CopyToAsync(Stream target, CancellationToken cancellationToken = null);
    }

    上面的代码使用了IHostingEnvironment来获取项目的根目录地址.

    构造函数注入的代码如下:

            private readonly IHostingEnvironment _hostingEnvironment;
    
            public UpLoadFileController(IHostingEnvironment hostingEnvironment)
            {
                _hostingEnvironment = hostingEnvironment;
            }

    这样,我们就完成了控制器的编写,然后到运行前端,上传文件..效果如下:

    通过IFormFile的CopyToAsync方法,我们就可以把这个文件流复制下来并保存到本地即可.

    2.使用Ajax上传文件

    上面我们是使用表单上传,但是项目过程中,大部分情况会使用Ajax进行上传,所以我们就来讲讲如何使用Ajax上传.

    首先编写HTML代码如下:

    <div>
        <form id="uploadForm">
            AJAX上传多文件: <input type="file" name="file" multiple />
            <input type="button" value="上传" onclick="doUpload()" />
        </form>
    </div>

    编写JS代码如下(这里我们使用FormData对象来上传):

     function doUpload() {
            var formData = new FormData($("#uploadForm")[0]);
            $.ajax({
                url: '@Url.Action("FileSave")',
                type: 'POST',
                data: formData,
                async: false,
                cache: false,
                contentType: false,
                processData: false,
                success: function (returndata) {
                    alert(returndata);
                },
                error: function (returndata) {
                    alert(returndata);
                }
            });
            }

    后台代码不做任何修改.我们会发现.直接在List<IFormFile> files中是无法获取到文件的.

    通过调试,我们可以发现,文件是上传成功的,但是放在了Request.Form.Files当中.

    所以修改后台代码如下:

    public async Task<IActionResult> FileSave()
    {
                var date = Request;
                var files = Request.Form.Files;
                long size = files.Sum(f => f.Length);
                string webRootPath = _hostingEnvironment.WebRootPath;
                string contentRootPath = _hostingEnvironment.ContentRootPath;
                foreach (var formFile in files)
                {
                    if (formFile.Length > 0)
                    {
    
                        string fileExt = GetFileExt(formFile.FileName); //文件扩展名,不含“.”
                        long fileSize = formFile.Length; //获得文件大小,以字节为单位
                        string newFileName = System.Guid.NewGuid().ToString() + "." + fileExt; //随机生成新的文件名
                        var filePath = webRootPath +"/upload/" + newFileName;
                        using (var stream = new FileStream(filePath, FileMode.Create))
                        {
                            
                            await formFile.CopyToAsync(stream);
                        }
                    }
                }
    
                return Ok(new { count = files.Count, size });
     }

    改为直接从Request.Form.Files中获取文件集合.~

    3.使用webUploader上传文件

    很久之前..呃..封装过一个webUploader的JS.如下:

    对百度WebUploader开源上传控件的二次封装,精简前端代码(两句代码搞定上传)

    对百度WebUploader的二次封装,精简前端代码之图片预览上传(两句代码搞定上传)

    ..我们也用封装好的JS来试试.HTML和JS代码如下,后台代码不需要修改,还是直接从Request.Form.Files获取即可:

    <div id="upfliediv"></div>
    $(function () {
    
    
            //实例化文件上传
    
            $("#upfliediv").powerWebUpload({
                    auto: true, fileNumLimit: 1
                });
            $("#upfliediv").CleanUpload();
    
        })

    上传效果如图:

    4.文件下载.

    上传了文件,我们当然需要下载.

    直接通过URL+地址下载是一种极其不安全的方式.这里我们采用返回流的形式来下载.

    后台代码如下:

            /// <summary>
            /// 文件流的方式输出        /// </summary>
            /// <returns></returns>
            public IActionResult DownLoad(string file)
            {
                var addrUrl = file;
                var stream = System.IO.File.OpenRead(addrUrl);
                string fileExt = GetFileExt(file);
                //获取文件的ContentType
                var provider = new FileExtensionContentTypeProvider();
                var memi = provider.Mappings[fileExt];
                return File(stream, memi, Path.GetFileName(addrUrl));
            }  

    这里值得注意的是,以前我们想获取ContentType直接使用MimeMapping.GetMimeMapping(file);就好了.

    但是这个类是在System.Web下的,core已经抛弃了现有的System.Web.

    所以在ASP.NET Core中我们需要通过新的类FileExtensionContentTypeProvider来获取文件的ContentType

    编写HTML+JS代码如下(PS:因为是demo,所以写的比较简陋):

    <div>
        <input type="text" id="filename" /><button onclick="downLoad()">下载</button>
    </div>
     function downLoad() {
                var filename = $("#filename").val();
                window.location.href = "@Url.Action("DownLoad")?file=" + filename;
    
            }

    效果如图:

    写在最后

    到此,本篇就结束了,感兴趣的,请点个关注或者推荐.~谢谢.博客也新增了ASP.NET Core的分类文章,以后关于ASP.NET Core的文章都会归类在里面.

  • 相关阅读:
    MySQL "show users"
    MySQL
    A MySQL 'create table' syntax example
    MySQL backup
    MySQL show status
    Tomcat, pathinfo, and servlets
    Servlet forward example
    Servlet redirect example
    Java servlet example
    How to forward from one JSP to another JSP
  • 原文地址:https://www.cnblogs.com/GuZhenYin/p/8194726.html
Copyright © 2011-2022 走看看