前言

以前得文章 Asp.net core 学习笔记 ( upload/download files 文件上传与下载 ), 这篇是修订版.

Handle Upload File (处理上传文件)

我的例子是基于 Web API 和 Ajax 的.

前端 Ajax

const btn = document.querySelector('button')!;
btn.addEventListener('click', async () => {
const formData = new FormData();
formData.append('file', createTextBlob('Hello World'), 'text1.txt');
// formData.append('file', createTextBlob('Derrick'), 'text2.txt'); // for multiple file await fetch('http://localhost:5221/Upload', {
method: 'POST',
body: formData,
}); function createTextBlob(text: string): Blob {
const textEncoder = new TextEncoder();
const bytes = textEncoder.encode(text);
return new Blob([bytes], {
type: 'text/plain',
});
}
});

upload 一个/多个 text file.

Web API

DTO

public class UploadDto
{
public IFormFile File { get; set; } = null!;
}

关键就是这个 IFormFile, 它就是用来接收前端 File 的.

Controller

[ApiController]
public class UploadController : ControllerBase
{
[HttpPost("Upload")]
[Consumes("multipart/form-data")]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult> Upload([FromForm] UploadDto dto)
{
return Ok("ok");
}
}

把 upload file 写入 disk

var fileRootFullPath = Path.Combine(AppContext.BaseDirectory, $@"..\..\..\{dto.File.FileName}");
using var fileStream = System.IO.File.Create(fileRootFullPath);
await dto.File.CopyToAsync(fileStream);

IFormFile 用法很简单, 它通过 .FileName 拿到文件名, 通过 CopyToAsync 把 stream 传给别人. 比如上面是把 stream 导入 file stream, 这样就写入磁盘了.

把 upload file stream 传给任何人使用

// 直接读 string 出来
using var stream = dto.File.OpenReadStream();
using var streamReader = new StreamReader(stream, encoding: Encoding.UTF8);
var text = await streamReader.ReadToEndAsync(); // Hello World

通过 OpenReadStream() 导出 stream 就可以做任何 stream 处理了.

handle multiple files

// JavaScript
const formData = new FormData();
formData.append('file', createTextBlob('Hello World'), 'text1.txt');
formData.append('file', createTextBlob('Derrick'), 'text2.txt'); // for multiple file // C#
public class UploadDto
{
public List<IFormFile> File { get; set; } = null!;
}

没什么提别的, 就只是换成了 List<IFormFile>

file size limit

ASP.NET Core 默认的 max upload file size 是 28.6 MB。

在 Program.cs

修改 Kestrel

builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{
serverOptions.Limits.MaxRequestBodySize = 157286400; // 150MB
});

修改 FormOptions

builder.Services.Configure<FormOptions>(options =>
{
options.MultipartBodyLengthLimit = 157286400; // 150 MB
});

Production IIS 的话,修改 web.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<security>
<requestFiltering>
<!-- Set the maximum allowed content length to 150 MB (in bytes) -->
<requestLimits maxAllowedContentLength="157286400" />
</requestFiltering>
</security>
<!-- Add other configurations as needed -->
</system.webServer>
</configuration>

Download File (下载文件)

前端 HTML

<a href="http://localhost:5221/Download" download="">download</a>

Web API Controller

[ApiController]
public class UploadController : ControllerBase
{
[HttpGet("Download")]
[Produces(MediaTypeNames.Text.Plain)]
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult Download()
{
return new FileContentResult(Encoding.UTF8.GetBytes("Hello World"), "text/plain")
{
FileDownloadName = "text.txt"
}; // 下面这个写法和上面是等价的
// return File(
// fileContents: Encoding.UTF8.GetBytes("Hello World"),
// contentType: "text/plain",
// fileDownloadName: "text.txt"
// );
}
}

返回 bytes, 声明 ContentType 和 Download File Name 就可以了. 简单

Force open save as dialog (showSaveFilePicker)

用 Chrome 下载文件的体验是,它会直接放到 default location folder 里,除非用户开启 “Ask where to save each file before downloading” 设置

Firefox 也是这样。无意间发现 pixlr.com 在 Chrome 可以 force open save as dialog。

我猜它用了一个比较新的 File System API : showSaveFilePicker。目前只有 Chrome 支持。

参考: Stack Overflow – Force showing the "Save as" dialog box when downloading a file

代码大致长这样

const canvas = document.querySelector<HTMLCanvasElement>('.img')!;
const ctx = canvas.getContext('2d')!;
const response = await fetch('https://192.168.1.152:4200/src/images/nana.jpg');
const blob = await response.blob();
const img = await createImageBitmap(blob);
[canvas.width, canvas.height] = [img.width, img.height];
ctx.drawImage(img, 0, 0); const btn = document.querySelector<HTMLElement>('.btn')!; btn.addEventListener('click', () => {
canvas.toBlob(async blob => {
// 关键:
const handle = await showSaveFilePicker({
suggestedName: 'nana.jpg',
types: [
{
description: 'Jpeg file',
accept: {
'image/jpeg': ['.jpeg', '.jpg'],
},
},
],
});
const writable = await handle.createWritable();
await writable.write(blob!);
writable.close();
}, 'image/jpeg');
});

不过这个方式下载的文件,不会出现在 Chrome 的 recently download 记入里面,体验有点差。

另外,目前 TypeScript 还不支持哦,需要

yarn add @types/wicg-file-system-access --dev

ASP.NET Core – Upload and Download Files (上传和下载文件)的更多相关文章

  1. MVC文件上传03-使用Request.Files上传多个文件

    本篇体验在控制器方法中使用controllerContext.HttpContext.Request.Files上传多个文件.兄弟篇为: MVC文件上传01-使用jquery异步上传并客户端验证类型和 ...

  2. Spring Boot之 Controller 接收参数和返回数据总结(包括上传、下载文件)

            一.接收参数(postman发送) 1.form表单 @RequestParam("name") String name 会把传递过来的Form表单中的name对应 ...

  3. 利用SecureCRT上传、下载文件(使用sz与rz命令),超实用!

    利用SecureCRT上传.下载文件(使用sz与rz命令),超实用! 文章来源:http://blog.csdn.net/dongqinliuzi/article/details/39623169 借 ...

  4. 每天一个linux命令(26)--用SecureCRT来上传和下载文件

    用SSH管理Linux 服务器时经常需要远程与本地之间交互文件,而直接使用 SecureCRT 自带的上传下载功能无疑是最方便的,SecureCRT下的文件传输协议有ASCII.Xmodem.Zmod ...

  5. oracle EBS上传和下载文件(转)

    最近一直在做一个工作流的项目,最终用户要求在发送消息的时候可以附带附件,这个又是给我的一个难题.在网上查了一下ORACLE上传资料,找到了黄建华前辈写的<Oracle EBS Forms开发指南 ...

  6. 【Loadrunner】使用LoadRunner上传及下载文件

    使用LoadRunner上传及下载文件 1)LoadRunner上传文件 web_submit_data("importStudent.do", "Action=http ...

  7. SecureCRT上传和下载文件

    SecureCRT上传和下载文件(下载默认目录) SecureCR 下的文件传输协议有ASCII .Xmodem .Ymodem .Zmodem ASCII:这是最快的传输协议,但只能传送文本文件. ...

  8. 11、只允许在主目录下上传和下载文件,不允许用putty登录

    创建用户xiao,   使其只允许在用户主目录 (/var/www/html)下上传和下载文件,不允许用putty登录 (为了安全起见,不给过多的权限) 1.创建xiao用户 [root@localh ...

  9. 每天一个linux命令(26):用SecureCRT来上传和下载文件

    用SSH管理linux服务器时经常需要远程与本地之间交互文件.而直接用SecureCRT自带的上传下载功能无疑是最方便的,SecureCRT下的文件传输协议有ASCII.Xmodem.Zmodem. ...

  10. Linux--用SecureCRT来上传和下载文件

    SecureCRT下的文件传输协议有以下几种:ASCII.Xmodem.Ymodem.Zmodem ASCII:这是最快的传输协议,但只能传送文本文件. Xmodem:这种古老的传输协议速度较慢,但由 ...

随机推荐

  1. SMOTE与SMOGN算法R语言代码

      本文介绍基于R语言中的UBL包,读取.csv格式的Excel表格文件,实现SMOTE算法与SMOGN算法,对机器学习.深度学习回归中,训练数据集不平衡的情况加以解决的具体方法.   在之前的文章S ...

  2. Java JVM——12. 垃圾回收理论概述

    1.前言 1.1 什么是垃圾? 在提到什么是垃圾之前,我们先看下面一张图: 从上图我们可以很明确的知道,Java 和 C++ 语言的区别,就在于垃圾收集技术和内存动态分配上,C++ 语言没有垃圾收集技 ...

  3. 基于Java+SpringBoot+vue+element助农平台设计和实现

    \n文末获取源码联系 感兴趣的可以先收藏起来,大家在毕设选题,项目以及论文编写等相关问题都可以给我加好友咨询 系统介绍: 随着互联网大趋势的到来,社会的方方面面,各行各业都在考虑利用互联网作为媒介将自 ...

  4. Profinet转Modbus模块减轻通讯编程工作量实现Modbus通讯

    巴图自动化PN转Modbus模块(BT-MDPN10)能够实现Profinet协议与Modbus协议之间的转换,使得Profinet协议设备与Modbus协议设备进行连接并能够相互通信. 通过使用巴图 ...

  5. [rCore学习笔记 03]配置rCore开发环境

    写在前面 本随笔是非常菜的菜鸡写的.如有问题请及时提出. 可以联系:1160712160@qq.com GitHhub:https://github.com/WindDevil (目前啥也没有 rCo ...

  6. 前缀函数及 Knuth–Morris–Pratt 算法学习笔记

    \(\text{1 引言 Preface}\) 对于形如以下的问题: 给予一个模式串 \(T\) 和主串 \(S\),在主串中寻找 \(T\). 我们称之为字符串匹配. 很显然朴素算法时间复杂度是 \ ...

  7. 关于mybatisplus与mybatis的自动填充混用问题

    public class MybatisPlusAutoFillHandler implements MetaObjectHandler { //插入时的填充策略 @Override public v ...

  8. 对精确率(P)、召回率(R)、F1值的理解以及对应的实现

    对精确率.召回率.F1值的理解 算法理解 在机器学习中,P.R和F1值在各种评测中很常见,那么到底什么是P.R.F1值呢,怎么理解呢,困扰了很多人,下面给我对P.R.F1值的理解, 首先,我们先看一个 ...

  9. 4、SpringBoot2之整合SpringMVC

    创建名为springboot_springmvc的新module,过程参考3.1节 4.1.重要的配置参数 在 spring boot 中,提供了许多和 web 相关的配置参数(详见官方文档),其中有 ...

  10. 【SQL】 去掉最后一段,只保留前段

    需求描述: 例如给出这样一个地址或者其他字符: 10.11.12.13 192.168.177.209101.102.103.104.105 ... 要求只保留前面的部分,去掉最后一部分 10.11. ...