前言

本君已成夜猫子,本节我们来讲讲ASP.NET Core MVC中的上传,这两天在研究批量导入功能,本节顺便简单搞搞导入、导出,等博主弄妥当了再来和大家一并分享。

.NET Core MVC上传

首先我们来看看官网的上传的例子,再然后进行拓展训练,官网的表单是这样的。

<form method="post" enctype="multipart/form-data" asp-controller="UploadFiles" asp-action="Index">
<div class="form-group">
<div class="col-md-10">
<p>Upload one or more files using this form:</p>
<input type="file" name="files" multiple />
</div>
</div>
<div class="form-group">
<div class="col-md-10">
<input type="submit" value="上传" />
</div>
</div>
</form>

在ASP.NET Core MVC中接收上传的文件需要用 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);
}

后台控制器关于上传的Action方法进行如下定义:

        [HttpPost("UploadFiles")]
public async Task<IActionResult> Post(List<IFormFile> files)
{
long size = files.Sum(f => f.Length); // full path to file in temp location
var filePath = Path.GetTempFileName(); foreach (var formFile in files)
{
if (formFile.Length > )
{
using (var stream = new FileStream(filePath, FileMode.Create))
{
await formFile.CopyToAsync(stream);
}
}
}
return Ok(new { count = files.Count, size, filePath });
}

为了很清楚地上传文件所在目录,我们将官网例子进行一下改造。

        public IActionResult UploadFiles(List<IFormFile> files)
{
long size = ;
foreach (var file in files)
{
//var fileName = file.FileName;
var fileName = ContentDispositionHeaderValue
.Parse(file.ContentDisposition)
.FileName
.Trim('"');
fileName = hostingEnv.WebRootPath + $@"\{fileName}";
size += file.Length;
using (FileStream fs = System.IO.File.Create(fileName))
{
file.CopyTo(fs);
fs.Flush();
}
}
ViewBag.Message = $"{files.Count}个文件 /{size}字节上传成功!";
return View();
}

如上通过注入  private IHostingEnvironment hostingEnv; 来获取网站根目录路径。在前台表单中请求action方法用渲染的方式,如下:

<form method="post" enctype="multipart/form-data" asp-controller="Upload" asp-action="UploadFiles">
</form>

当然别忘记添加TagHelper:

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

成功上传我们显示上传字节大小,如下:

上传的文件在网站根目录下我们能够看到,如下:

上述我们只是牛刀小试通过表单提交,接下来我们进行拓展通过Ajax来提交。我们将表单类型submit修改为button,如下:

         <div class="row">
<div class="form-group">
<div class="col-md-10">
<p>使用表单上传多个文件</p>
<input type="file" id="files" name="files" multiple />
@ViewBag.Message
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<div class="col-md-10">
<input type="button" id="upload" class="btn btn-success" style="cursor:pointer;width:100px;" value="上传" />
</div>
</div>
</div>

我们通过FormData对象来获取文件从而进行Ajax提交,如下:

         $(function () {
$("#upload").click(function (evt) {
var fileUpload = $("#files").get();
var files = fileUpload.files;
var data = new FormData();
for (var i = ; i < files.length ; i++) {
data.append(files[i].name, files[i]);
}
$.ajax({
type: "POST",
url: "/Upload/UploadFiles",
contentType: false,
processData: false,
data: data,
success: function (message) {
alert(message);
},
error: function () {
alert("上传文件出现错误!");
}
});
});
});

此时后台则需要进行略微修改,我们不再需要IFormFile接口来获取文件,通过请求中的表单获取,如下:

        public IActionResult UploadFiles()
{
long size = ;
var files = Request.Form.Files;
foreach (var file in files)
{
//var fileName = file.FileName;
var fileName = ContentDispositionHeaderValue
.Parse(file.ContentDisposition)
.FileName
.Trim('"');
fileName = hostingEnv.WebRootPath + $@"\{fileName}";
size += file.Length;
using (FileStream fs = System.IO.File.Create(fileName))
{
file.CopyTo(fs);
fs.Flush();
}
}
ViewBag.Message = $"{files.Count}个文件 /{size}字节上传成功!";
return View();
}

到这里关于ASP.NET Core MVC中的上传就告一段落,还是比较简单但是算是比较常见的需求。

导入、导出Excel

项目中需要用到批量导入和导出于是进行了一点研究,.net core刚出世时还未有对于.net core中Excel的导出,但是见过园中有热心园友分享并制作了.net core中导出Excel,但是博主发现在2月19号有老外已针对.net core的Excel导出和导入目前版本为1.3基于EPPlus,功能和EPPlus差不多,不过是移植到了.net core中,下面我们一起来看看。首先我们下载EPPlus.Core程序包,如下:

我们直接上导出代码:

        [HttpGet]
[Route("Export")]
public string Export()
{
string sWebRootFolder = _hostingEnvironment.WebRootPath;
string sFileName = @"Jeffcky.xlsx";
string URL = string.Format("{0}://{1}/{2}", Request.Scheme, Request.Host, sFileName);
FileInfo file = new FileInfo(Path.Combine(sWebRootFolder, sFileName));
if (file.Exists)
{
file.Delete();
file = new FileInfo(Path.Combine(sWebRootFolder, sFileName));
}
using (ExcelPackage package = new ExcelPackage(file))
{
// add a new worksheet
ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("Jeffcky"); //sheet header
worksheet.Cells[, ].Value = "ID";
worksheet.Cells[, ].Value = "Name";
worksheet.Cells[, ].Value = "Age"; //Add values
worksheet.Cells["A2"].Value = ;
worksheet.Cells["B2"].Value = "Jeffcky1";
worksheet.Cells["C2"].Value = ; worksheet.Cells["A3"].Value = ;
worksheet.Cells["B3"].Value = "Jeffcky2";
worksheet.Cells["C3"].Value = ; package.Save(); //Save the workbook.
}
return URL; }

这里我们进行统一封装下来进行导出只需要设置导出属性和列表数据即可,如下:

        public IActionResult Export()
{
var properties = new PropertyByName<Person>[]
{
new PropertyByName<Person>("Id",d=>d.Id),
new PropertyByName<Person>("Name",d=>d.Name),
new PropertyByName<Person>("Age",d=>d.Age)
}; var list = new List<Person>()
{
new Person() {Id=,Name="Jeffcky1",Age= },
new Person() {Id=,Name="Jeffcky2",Age= },
new Person() {Id=,Name="Jeffcky3",Age= },
new Person() {Id=,Name="Jeffcky4",Age= },
new Person() {Id=,Name="Jeffcky5",Age= }
};
var bytes = _ExportManager.ExportToXlsx<Person>(properties, list);
return new FileContentResult(bytes, MimeTypes.TextXlsx);
}

说完导出我们再来看导入,我们来读取刚刚导入的数据返回到页面上:

        public string Import()
{
string sWebRootFolder = _hostingEnvironment.WebRootPath;
string sFileName = @"Jeffcky.xlsx";
FileInfo file = new FileInfo(Path.Combine(sWebRootFolder, sFileName));
try
{
using (ExcelPackage package = new ExcelPackage(file))
{
StringBuilder sb = new StringBuilder();
ExcelWorksheet worksheet = package.Workbook.Worksheets[];
int rowCount = worksheet.Dimension.Rows;
int ColCount = worksheet.Dimension.Columns;
bool bHeaderRow = true;
for (int row = ; row <= rowCount; row++)
{
for (int col = ; col <= ColCount; col++)
{
if (bHeaderRow)
{
sb.Append(worksheet.Cells[row, col].Value.ToString() + "\t");
}
else
{
sb.Append(worksheet.Cells[row, col].Value.ToString() + "\t");
}
}
sb.Append(Environment.NewLine);
}
return sb.ToString();
}
}
catch (Exception ex)
{
return "Some error occured while importing." + ex.Message;
}
}

此时我们再来对导入进行统一封装下,如下:

        [HttpGet]
[Route("Import")]
public void Import()
{
string sWebRootFolder = _hostingEnvironment.WebRootPath;
string sFileName = @"Jeffcky.xlsx";
FileStream fs = new FileStream(Path.Combine(sWebRootFolder, sFileName), FileMode.Open, FileAccess.Read, FileShare.Read);
var list = _ImportManager.ImportPersonFromXlsx(fs);
}

导入大概就介绍完毕了,要我说真正的难点不在于利用EPPlus导入和导出,难点在于批量导入,批量进行导入后对数据格式的检验,如果给定一个导入模板,然后再导入批量数据怎么确保用户给的数据格式完全是正确的以及数据没有重复的校验,这两天基本上是完成了批量的导入,大概分为:数据必填项的校验、数据格式的校验、数据库是否存在数据的校验、数据导入部分导入失败返回格式的用户体验。当利用NPOI、EPPlus来导入和导出这样的功能再简单不过了,但是如果遇到了不同的场景怎么让用户体验更好的使用这是一个问题,如果数据导入失败我们怎么去提示用户呢,还有如果Excel中有下拉框和合并的单元格数据我们怎么去获取这又是一个问题,可能很多简历上写着会利用NPOI和EPPlus的导入和导出,其实没什么看头,二者不过是一个工具罢了,如何利用工具去应用到复杂的场景并举例那才算是高级的东西。

总结

本节我们稍微介绍了.net core中的下载、导入和导出,如果有可能的话后续会给出关于EPPlus中高级的知识,比如如上提出的获取合并列数据还有获取图片等等,我们下节再会,哦,关于SQL Server有时间会定期进行更新,see u。

ASP.NET Core MVC上传、导入、导出知多少的更多相关文章

  1. 改造kindeditor支持asp.net core mvc上传文件

    kindtor默认使用的上传方法是使用目录下面的一般处理程序upload_json.ashx,暂时还不支持asp.net core下的文件上传,下面放出的自定义处理上传文件的接口方法. 自定义接收上传 ...

  2. asp.net core mvc上传大文件解决方案

    默认上传文件大小不超过30M 第一个问题: IIS 10.0 详细错误 - 404.13 - Not Found 请求筛选模块被配置为拒绝超过请求内容长度的请求. 服务器上的请求筛选被配置为拒绝该请求 ...

  3. ASP.NET Core MVC上传文件

    使用模型绑定上传小文件 HTML代码: <form method="post" enctype="multipart/form-data" asp-con ...

  4. [转载]ASP.NET Core文件上传与下载(多种上传方式)

    ASP.NET Core文件上传与下载(多种上传方式)   前言 前段时间项目上线,实在太忙,最近终于开始可以研究研究ASP.NET Core了. 打算写个系列,但是还没想好目录,今天先来一篇,后面在 ...

  5. ASP.NET Core文件上传IFormFile于Request.Body的羁绊

    前言 在上篇文章深入探究ASP.NET Core读取Request.Body的正确方式中我们探讨了很多人在日常开发中经常遇到的也是最基础的问题,那就是关于Request.Body的读取方式问题,看是简 ...

  6. asp.net core分块上传文件

    写完asp.net多文件上传(http://www.cnblogs.com/bestckk/p/5987383.html)后,感觉这种上传还是有很多缺陷,于是...(省略一万字,不废话).这里我没用传 ...

  7. Asp.Net Core 文件上传处理

    本文主要介绍后台接收处理 1.在使用控制器接收 : [HttpPost] : public IActionResult UploadFiles(IList<IFormFile> files ...

  8. ASP.NET Core文件上传与下载(多种上传方式)

    前言 前段时间项目上线,实在太忙,最近终于开始可以研究研究ASP.NET Core了. 打算写个系列,但是还没想好目录,今天先来一篇,后面在整理吧. ASP.NET Core 2.0 发展到现在,已经 ...

  9. ASP.NET Core 文件上传

    前言 上篇博文介绍了怎么样在 asp.net core 使用 Redis 和 Protobuf 进行 Session缓存.本篇的是开发过程中使用的一个小功能,怎么做单文件和多文件上传. 如果你觉得对你 ...

随机推荐

  1. linux上编译安装python2.7.5

    下载python2.7.5,保存到 /data/qtongmon/software http://www.python.org/ftp/python/ 解压文件 tar xvf Python-2.7. ...

  2. centos5.5關閉ssh保留運行的程序

    SSH会话关闭时,ssh所关联的pty关闭,系统会给这个pty所关联的session中的所有进程发送SIGHUP信号, SIGHUP的默认信号处理程序是终止进程,除非进程自己处理了SIGHUP. 解决 ...

  3. iOS 之 static

    函数体内的static变量的作用范围是该函数体,在内存中只分配一次,下次调用时仍维持上次的值. 模块内的static全局变量可以被模块内的所有函数访问,但是不能被模块外的其它函数访问. 模块内的sta ...

  4. HTML 相同name 传递一个数组

    今天发现一个很厉害的东西 在input表单中,name名称可以是一个,后面[],里面跟名称,和数组一样,传递到PHP中也是一个数组 <html> <body> <form ...

  5. JavaSE学习总结(一)——Java基础

    一.Java是什么 Java 是由 Sun Microsystems 在 1995 年首先发布的编程语言和计算平台.Java 是一项用于开发应用程序的技术,可以让 Web 变得更有意思和更实用.有许多 ...

  6. git 配置SSH免密

    1.安装TortoiseGit(比较简单,直接在官网上下载安装包安装) 2.打开下图标识 点击 generate按钮 生成key(需要等一会)   3.生成Key保存成.ppk文件,记得存放路径,(建 ...

  7. eclipse 开始运行提示 Java was started but returned exit code=13

    Eclipse 是一个开放源代码的.基于Java的可扩展开发平台.就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境. 当我们安装使用时,会出现eclipse启动不了,出现" ...

  8. OpenCV教程二 - Mat对象与它各种用法

    学习OpenCV大家都会遇到一个对象叫做Mat,此对象非常神奇,支持各种操作.很多初学者因此被搞得头晕脑胀,它各种用法太多太杂,搞得初学者应接不暇,感觉有心无力.无处下手之感.这里我们首先要正本清源, ...

  9. (一)Redis在windows下的安装和使用

    1.下载redis服务端,地址:https://github.com/MSOpenTech/redis/releases 包含安装程序和源码. 2.解压<Redis-x64-3.2.100.zi ...

  10. iOS之内存分析

    静态内存分析(Product->Analyze) 静态内存分析是不运行程序,直接对代码进行分析. 但是没有真正分配内存,根据代码的上下文的语法结构,来分析是否有内存泄露 缺点:不一定准确,但是如 ...