title

author

date

CreateTime

categories

asp dotnet core 支持客户端上传文件

lindexi

2019-08-31 16:55:58 +0800

2019-2-17 14:45:9 +0800

dotnet

本文告诉大家如何在 asp dotnet core 支持客户端上传文件

新建一个 asp dotnet core 程序,创建一个新的类,用于给客户端上传文件的信息

public class KanajeaLolowge
{
public IFormFile File { get; set; }

public string Sha { get; set; }
}


这个类包含两个信息,一个是 File 文件,另一个是文件校验,这个类可以随意命名,属性也可以随意命名,只要在客户端可以相同

打开一个 controller 添加一个新的函数

[HttpPost("UploadPackage")]
public async Task<StatusCodeResult> UploadPackage([FromForm]KanajeaLolowge file)
{

return Ok();
}


在这个函数添加特性 HttpPost 里面的参数就是访问链接,如上面的代码,加入所在的类是这样定义

[Route("api/[controller]")]
[ApiController]
public class GairKetemRairsemsController : ControllerBase


那么可以通过 ​​api/GairKetemRairsems/UploadPackage​​ 访问这个函数

在函数传入的参数使用 ​​[FromForm]KanajeaLolowge file​​ 的意思是通过 Post 提交 Form 的方法拿到参数

所以在客户端通过 Form 提交包含 File 和 Sha 信息的 Form 就可以通过链接调用这个方法

请看在客户端如何写

假设已经拿到文件的 FileStream 和计算出文件的 Sha 拿到链接

private static async Task Upload(FileStream fileStream, string sha, string url)


在这个方法上传文件,通过 MultipartFormDataContent 构造一个 Form 请看代码

var multipartFormDataContent = new MultipartFormDataContent();
multipartFormDataContent.Add(new StreamContent(fileStream), "File", fileName: "文件名.png");
multipartFormDataContent.Add(new StringContent(sha), "Sha");


文件通过 StreamContent 传入 Stream 的值,加上的 File 参数是和 asp dotnet core 的上传类对应的属性名,最后的一个 fileName 指的是文件名,因为传入的是 Stream 可能是内存流,这时就无法拿到文件名,需要用户传入

下面的值是传入一个 Key value 的值,这里的 key 是 ​​"Sha"​​ 值是 sha 的值

创建一个 HttpClient 上传 Form 代码

var httpClient = new HttpClient();
await httpClient.PostAsync(url, multipartFormDataContent);


这样调用这个 PostAsync 在 Asp dotnet core 就调用 UploadPackage 方法

通过这个方法就可以做到在 asp dotnet core 上传文件

获取文件 Sha 的方法请看下面

var fileStream = fileInfo.OpenRead();
string fileSha;
using (var sha = SHA256.Create())
{
fileSha = Convert.ToBase64String(sha.ComputeHash(fileStream));

fileStream.Seek(0, SeekOrigin.Begin);
}


注意需要 fileStream 还原,也就是 ​​fileStream.Seek(0, SeekOrigin.Begin)​​ 如果没有添加,那么上传的 Stream 是没有长度

在 asp dotnet core 接收文件,然后校验文件的方法请看下面

[HttpPost("UploadPackage")]
public async Task<StatusCodeResult> UploadPackage([FromForm]KanajeaLolowge file)
{
var fileInfo = new FileInfo("E:\\1.png");

var fileStream = fileInfo.Open(FileMode.Create, FileAccess.ReadWrite);

await file.File.CopyToAsync(fileStream);

fileStream.Seek(0, SeekOrigin.Begin);

string fileSha;
using (var sha = SHA256.Create())
{
fileSha = Convert.ToBase64String(sha.ComputeHash(fileStream));

fileStream.Seek(0, SeekOrigin.Begin);
}

if (fileSha == file.Sha)
{
return Ok();
}

return BadRequest();
}


如果需要将文件保存在 ContentRoot 可以通过在 controller 的构造函数添加 IHostingEnvironment 参数,在 IHostingEnvironment 参数拿到 ContentRootPath 值

public GairKetemRairsemsController(IHostingEnvironment hostingEnvironment)
{
_context = context;
_hostingEnvironment = hostingEnvironment;
}

private readonly IHostingEnvironment _hostingEnvironment;


在保存文件可以使用下面代码

var fileInfo = new FileInfo(Path.Combine(_hostingEnvironment.ContentRootPath, "1.png"));