asp.net zero 8.2 学习-12- abp 文件上传、获取、删除

1. 页面布局

我们先按照第二讲的方法 创建一个页面 创建出一个空页面。
先创建一个Controller,比如MetronicController,再创建一个Action方法:UploadFile,再给UploadFile方法添加一个视图,复制空页面的内容到该视图UploadFile.cshtml
接着写上传文件的form表单
整体视图如下:

@using EDU.SIS.Web.Areas.app.Startup
@using EDU.SIS.Authorization

@{
    ViewBag.CurrentPageName = appPageNames.Common.MetronicUploadFile;
}



文件上传

选择文件
上传进度
附件详情将在控制台输出
删除附件
@section Scripts{ }

2. 前端js

在页面的Index.js文件种编写javascript脚本,这里使用了一个前端上传文件的jquery插件:jquery.fileupload.js,这个插件是在视图布局文件中已经绑定了压缩打包版app-layout-libs,不用再单独引用。
Index.js源码如下:

(function () {
    $(function () {
        //--------------------------------- 系统附件上传 ---------------------------------//
        var url = abp.appPath + 'app/Metronic/UploadFilePost';
        $('#fileupload').fileupload({
            url: url,    //后台上传服务地址
            dataType: 'json',
            add: function (e, data) { //选择文件后处理方法
                var files = data.originalFiles;
                var isCheckSuccess = true;
                if (files && files.length > 0) {
                    $(files).each(function (i, obj) {
                        //文件上传大小:10MB
                        var _maxFileSize = 1024 * 1024 * 10;
                        if (obj.size > _maxFileSize) {
                            isCheckSuccess = false;
                            abp.message.error("文件大小不能超过10MB");
                            return;
                        }
                        //判断文件类型
                        var acceptFileTypes = /^gif|jpe?g|png|bmp$/i;
                        var name = data.originalFiles[0]["name"];
                        var index = name.lastIndexOf(".") + 1;
                        var fileType = name.substring(index, name.length);

                        if (!acceptFileTypes.test(fileType)) {
                            isCheckSuccess = false;
                            abp.message.error("只允许上传图片格式文件");
                            return;
                        }
                    });
                }

                //校验成功后才提交上传数据
                if (isCheckSuccess) {

                    //上传按钮禁用状态
                    $('#fileupload').attr("disabled", "disabled");
                    $('.fileinput-button').addClass("disabled");

                    //提交上传数据
                    data.submit();
                }

            },

            done: function (e, response) { //上传完成后结果返回处理
                //解除上传按钮禁用状态
                $('#fileupload').removeAttr("disabled");
                $('.fileinput-button').removeClass("disabled");

                var jsonResult = response.result;

                //判断上传状态
                if (jsonResult.success) {
                    var fileUrl = abp.appPath + 'app/Metronic/GetFile?id=' + jsonResult.result.id + '&contentType=' + jsonResult.result.contentType; //注意contentType首字母要小写
                    var uploadedFile = '' + app.localize('UploadedFile') + '

' + ' 文件名称: ' + jsonResult.result.defaultFileName; //赋值附件名称 $('#txt_fileName').val(jsonResult.result.defaultFileName); //赋值隐藏域上传附件ID $('#txt_uploadFileId').val(jsonResult.result.id); //赋值获取附件详情文本框 $('#txt_enclosureId').val(jsonResult.result.id); //弹出成功提示框 abp.message.success(jsonResult.result.defaultFileName, app.localize('PostedData'), true); //弹出成功通知 abp.notify.success(app.localize('SavedSuccessfully')); } else { abp.message.error(jsonResult.error.message); } }, progressall: function (e, data) { //上传进度处理 var progress = parseInt(data.loaded / data.total * 100, 10); $('#progress .progress-bar').css( 'width', progress + '%' ); } }); //获取附件上传表单对象 var _$formUpload = $("#kt_form_upload"); //启用表单验证 _$formUpload.validate(); //获取详情按钮点击事件 $('#btn_get_enclosure').on('click', function () { //校验附件ID输入 var _validStatus = $('#txt_enclosureId').valid(); //判断校验结果 if (_validStatus) { var url = abp.appPath + 'app/Metronic/GetFileDetail?id=' + $('#txt_enclosureId').val(); $.get(url, function (data) { console.log(data); abp.notify.success("获取数据详情成功,请前往控制台查看。"); }); } }); //删除附件 $('#btn_delete_file').on('click', function () { //校验附件ID输入 var _validStatus = $('#txt_fileToDeleteId').valid(); if (_validStatus) { var url = abp.appPath + 'app/Metronic/DeleteFile?id=' + $('#txt_fileToDeleteId').val(); $.get(url, function (data) { if (data.success) { abp.notify.success("删除文件成功"); } else { //console.log(data); abp.notify.info("删除文件失败:"+data.error.message); } }) } }); }); })();

3. 后端代码

后端与上传文件相关的代码包括领域实体层的BinaryObject,这里对其扩展,添加了文件类型、大小等相关字段:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Abp;
using Abp.Domain.Entities;

namespace EDU.SIS.Storage
{
    /// 
    /// 附件实体
    /// 
    [Table("AppBinaryObjects")]
    public class BinaryObject : Entity, IMayHaveTenant
    {
        /// 
        /// 租户ID
        /// 
        public virtual int? TenantId { get; set; }

        /// 
        /// 文件类型【拓展字段】
        /// 
        public virtual string ContentType { get; set; }

        /// 
        /// 文件名称【拓展字段】
        /// 
        public virtual string FileName { get; set; }

        /// 
        /// 文件大小【拓展字段】
        /// 
        public virtual long FileSize { get; set; }

        /// 
        /// 二进制数据
        /// 
        [Required]
        public virtual byte[] Bytes { get; set; }

        public BinaryObject()
        {
            Id = SequentialGuidGenerator.Instance.Create();
        }

        public BinaryObject(int? tenantId, byte[] bytes)
            : this()
        {
            TenantId = tenantId;
            Bytes = bytes;
        }
    }
}

还包括IBinaryObjectManager、DbBinaryObjectManager实现文件上传的领域服务,未修改。
接下来就是在Controller中编写上传文件处理、获取文件详情等方法:

/// 
        /// 上传文件界面
        /// 
        /// 
        [HttpGet]
        public IActionResult UploadFile()
        {
            return View();
        }

        /// 
        /// 文件上传
        /// 
        /// 
        [HttpPost]
        public async Task UploadFilePost()
        {
            try
            {
                //获取上传对象
                var file = Request.Form.Files.First();

                //判断是否选择文件
                if (file == null)
                {
                    throw new UserFriendlyException(L("File_Empty_Error"));
                }

                //判断文件大小(单位:字节)
                if (file.Length > 10485760) //10MB = 1024 * 1024 *10
                {
                    throw new UserFriendlyException(L("File_SizeLimit_Error"));
                }

                //将文件流转为二进制数据
                byte[] fileBytes;
                using (var stream = file.OpenReadStream())
                {
                    fileBytes = stream.GetAllBytes();
                }

                

                //创建附件对象
                var fileObject = new BinaryObject()
                {
                    TenantId = AbpSession.TenantId,
                    Bytes = fileBytes,
                    ContentType = file.ContentType,
                    FileName = file.FileName,
                    FileSize = file.Length
                };

                //上传文件存储路径
                string destPath = _webHostEnvironment.WebRootPath + "\\uploads\\";
                if (!Directory.Exists(destPath))
                {
                    Directory.CreateDirectory(destPath);
                }
                //生成随机文件名
                var fileExtension = Path.GetExtension(file.FileName).ToLowerInvariant();
                string fileName = fileObject.Id + fileExtension;//需要查找没有扩展名的文件??
                string filePath = Path.Combine(destPath, fileName);
                //存放文件到本地
                using (FileStream fs = System.IO.File.Create(filePath))
                {
                    file.CopyTo(fs);
                    fs.Flush();
                }

                //附件对象保存到数据库
                await _binaryObjectManager.SaveAsync(fileObject);

                //返回给前端上传结果
                return Json(new AjaxResponse(new
                {
                    id = fileObject.Id,
                    contentType = file.ContentType,
                    defaultFileName = file.FileName
                }));

            }
            catch (UserFriendlyException ex)
            {
                return Json(new AjaxResponse(new ErrorInfo(ex.Message)));
            }
            catch(Exception ex)
            {
                return Json(new AjaxResponse(new ErrorInfo(ex.Message)));
            }
        }

        /// 
        /// 删除文件
        /// 
        /// 
        /// 
        public async Task DeleteFile(string id)
        {
            try
            {
                var fileId = new Guid(id);
                var fileToDelete = await _binaryObjectManager.GetOrNullAsync(fileId);
                if (fileToDelete != null)
                {
                    //string filePath = _webHostEnvironment.WebRootPath + "\\uploads\\"+ fileToDelete.FileName;
                    await _binaryObjectManager.DeleteAsync(fileId);
                    return Json(new AjaxResponse(true));
                }
                else
                {
                    return Json(new AjaxResponse(new ErrorInfo
                    {
                        Message = "文件不存在或删除文件失败"
                    }));
                }
            }
            catch (Exception)
            {
                return Json(new AjaxResponse(new ErrorInfo
                {
                    Message = "文件ID无效"
                }));
            }
            
        }

        /// 
        /// 获取附件
        /// 
        /// 附件ID
        /// 附件类型
        /// 
        public async Task GetFile(Guid id, string contentType)
        {
            var fileObject = await _binaryObjectManager.GetOrNullAsync(id);
            if (fileObject == null)
            {
                return StatusCode((int)HttpStatusCode.NotFound);
            }

            return File(fileObject.Bytes, contentType);
        }

        /// 
        /// 获取附件详情
        /// 
        /// 附件ID
        /// 
        [HttpGet]
        public async Task GetFileDetail(Guid id)
        {
            var fileObject = await _binaryObjectManager.GetOrNullAsync(id);
            if (fileObject == null)
            {
                return StatusCode((int)HttpStatusCode.NotFound);
            }

            return Json(new AjaxResponse(new
            {
                id = fileObject.Id,
                fileName = fileObject.FileName,
                contentType = fileObject.ContentType,
                fileSize = fileObject.FileSize,
                fileSizeFormat = FormatFileSize(fileObject.FileSize),
                bytes = fileObject.Bytes,
                tenantId = fileObject.TenantId,
                downloadUrl = string.Format("{0}app/Metronic/GetFile?id={1}&contentType={2}", _appConfiguration["App:WebSiteRootAddress"], fileObject.Id, fileObject.ContentType)
            }));
        }

这里abp官方上传的文件都是存放在数据库中,对于存放大的文件很不科学。可以修改代码存放到本地,也可以参考Magicodes.Storage这个开源库,实现本地存储或者云端OSS存储。

4. 系统文件上传大小限制

系统文件上传大小限制可以在代码中实现,也可以通过配置实现,但是最大不会超过配置内规定的大小,在MVC项目的Web.config中修改最大上传大小限制

...
    
      
        
        
      
    
  
  
    
    
  

5. 测试

image

你可能感兴趣的:(asp.net zero 8.2 学习-12- abp 文件上传、获取、删除)