.Net Web API 005 Controller上传小文件
1、附属文件对象定义
一般情况下,系统里面的文件都会附属一个对象存在,例如用户的头像文件,会附属用户对象存在。邮件中的文件会附属邮件存在。所以在系统里面,我们会创建一个附属文件对象,命名为AttachedFileEntity。其定义如下所示。
/// <summary>
/// 附属文件实体对象
/// </summary>
public class AttachedFileEntity
{ /// <summary>
/// 实体对象GUID
/// </summary>
public string GUID { get; set; } = ""; /// <summary>
/// 所属对象的GUID
/// </summary>
public string EntityGUID { get; set; } = ""; /// <summary>
/// 名称
/// </summary>
public string Name { get; set; } = ""; /// <summary>
/// 关键字
/// </summary>
public string KeyWord { get; set; } = ""; /// <summary>
/// 文件大小
/// </summary>
public int FileSize { get; set; } = 0; /// <summary>
/// 服务器存储路径
/// </summary>
public string ServerPath { get; set; } = ""; /// <summary>
/// 描述信息
/// </summary>
public string Description { get; set; } = ""; }
EntityGUID属性的作用是,定义该文件属于哪个实体对象,例如某个用户的头像文件,该属性就是这个用户对象的GUID值。
KeyWord属性用来标识文件。例如UserEntity有两个文件,头像和一个自我介绍的视频文件。这两个文件的EntityGUID都是UserEntity的GUID,那么就可以通过KeyWord来区分两个文件是做什么用的。
2、小文件上传服务
如果一个文件比较小,例如3M以内,那么我们就可以一次性把文件上传上来,上传的时候,要把AttachedFileEntity对象传进来,并添加到数据库中。
代码如下所示。
/// <summary>
/// 上传文件
/// </summary>
/// <param name="pEntity"></param>
/// <returns></returns>
[HttpPost]
[Route("UploadFile")]
public IActionResult UploadFile()
{
//获取客户端传来的数据
var myEntityJosnString = Request.Form["pEntity"].ToString();
var myEntity = JsonSerializer.Deserialize<AttachedFileEntity>(myEntityJosnString);
var myFile = Request.Form.Files[0]; //设置新的文件路径
string myFileEx = Path.GetExtension(myFile.FileName);
string myServerFilePath = DateTime.Now.ToString("yyyy_MM_dd") + "\\" + Guid.NewGuid().ToString() + myFileEx;
myEntity!.ServerPath = myServerFilePath; //创建目录
string myFullServerPath = AppDomain.CurrentDomain.BaseDirectory + "\\Files\\" + myServerFilePath;
string myFullFolder = Path.GetDirectoryName(myFullServerPath)!;
if (Directory.Exists(myFullFolder) == false)
{
Directory.CreateDirectory(myFullFolder);
} Stream? myStream = null;
FileStream? myFileStream = null;
BinaryWriter? myBinaryWriter = null;
try
{
myStream = myFile.OpenReadStream();
byte[] myBytes = new byte[myStream.Length];
myStream.Read(myBytes, 0, myBytes.Length);
myStream.Seek(0, SeekOrigin.Begin); myFileStream = new FileStream(myFullServerPath, FileMode.Create);
myBinaryWriter = new BinaryWriter(myFileStream);
myBinaryWriter.Write(myBytes);
}
finally
{
myBinaryWriter?.Close();
myFileStream?.Close();
myStream?.Close();
} //把附属文件对象保存到数据库中
//代码略 return this.Ok(myEntity);
}
因为我们要传入两个复杂的对象AttachedFileEntity和File,所以就不能用参数接了,就需要用代码从Request里面读取。文件其本质就是二进制数据,我们获取这个二进制之后,把数据保存成文件就可以了。然后把pEntity写入到数据库中。
3、前端调用
先用桌面端测试,界面是用C#写的WPF桌面软件,入下图所示。

调用代码入下所示。
var myFilePath = this.UI_SmallFile_TextBox.Text.Trim();
if (myFilePath.Length == 0)
{
MessageBox.Show("请选择一个文件。");
return;
}
if (File.Exists(myFilePath) == false)
{
MessageBox.Show("文件不存在,请重新选择。");
return;
} //定义AttachedFileEntity
var myAttachedFileEntity = new AttachedFileEntity()
{
GUID = Guid.NewGuid().ToString(),
Name = "用户头像",
KeyWord = "UserProfilePhoto",
Description = "",
EntityGUID = "AAAA"
}; //定义请求内容
var myFileStream = new FileStream(myFilePath, FileMode.Open);
myAttachedFileEntity.FileSize = (int)myFileStream.Length;
var myFileName = Path.GetFileName(myFilePath);
var myFileStreamContent = new StreamContent(myFileStream);
var myMultipartFormDataContent = new MultipartFormDataContent
{
{ JsonContent.Create(myAttachedFileEntity), "pEntity" },
{ myFileStreamContent, "pFormFile", myFileName }
}; //请求服务
var myHttpClientEx = new HttpClientEx(new HttpClient())
{
Url = "http://localhost:5000/api/AttachedFile/UploadFile",
HttpContent = myMultipartFormDataContent
};
await myHttpClientEx.PostAsync();
myFileStream.Close(); //解析结果
if (myHttpClientEx.IsSuccess == false)
{
MessageBox.Show(("上传文件失败," + myHttpClientEx.ResponseContenString));
return;
}
var myEntity = myHttpClientEx.GetResponseObject<AttachedFileEntity>();
var myEntityJosnString = JsonSerializer.Serialize(myEntity);
MessageBox.Show(myEntityJosnString);
HttpClientEx是对.Net定义的HttpClient一些功能的扩展,这样用起来会比较方便,代码定义如下。
/// <summary>
/// HttpClient的自定义扩展类
/// </summary>
public class HttpClientEx
{ /// <summary>
/// HttpClient的自定义扩展类
/// </summary>
/// <param name="pHttpClient"></param>
public HttpClientEx(HttpClient? pHttpClient)
{
this.HttpClient = pHttpClient;
this.ParameterDictionary = new Dictionary<string, string>();
} /// <summary>
/// HttpClient对象
/// </summary>
public HttpClient? HttpClient { get; private set; } /// <summary>
/// 服务地址
/// </summary>
public string Url { get; set; } = ""; /// <summary>
/// 参数字典
/// </summary>
public Dictionary<string, string> ParameterDictionary { get; private set; } /// <summary>
/// 请求内容
/// </summary>
public HttpContent? HttpContent { get; set; } /// <summary>
/// 请求返回的消息
/// </summary>
public HttpResponseMessage? ResponseMessage { get; private set; } /// <summary>
/// 是否执行成功
/// </summary>
public bool IsSuccess { get; private set; } /// <summary>
/// 返回的内容字符串
/// </summary>
public string ResponseContenString { get; private set; } = ""; /// <summary>
/// Get
/// </summary>
/// <returns></returns>
public async Task GetAsync()
{
var myUrlWithParameters = this.GetUrlWithParameters();
this.ResponseMessage = await this.HttpClient!.GetAsync(myUrlWithParameters);
this.IsSuccess = this.ResponseMessage.IsSuccessStatusCode;
this.ResponseContenString = await this.ResponseMessage.Content.ReadAsStringAsync();
} /// <summary>
/// Get
/// </summary>
/// <returns></returns>
public async Task PostAsync()
{
var myUrlWithParameters = this.GetUrlWithParameters();
this.ResponseMessage = await this.HttpClient!.PostAsync(myUrlWithParameters, this.HttpContent);
this.IsSuccess = this.ResponseMessage.IsSuccessStatusCode;
this.ResponseContenString = await this.ResponseMessage.Content.ReadAsStringAsync();
} /// <summary>
/// 得到返回的对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T? GetResponseObject<T>()
{
if (this.ResponseContenString == "")
{
return default;
}
var myJsonSerializerOptions = new JsonSerializerOptions()
{
PropertyNameCaseInsensitive = true
};
return JsonSerializer.Deserialize<T>(this.ResponseContenString, myJsonSerializerOptions);
} /// <summary>
/// 得到带参数的Url
/// </summary>
/// <returns></returns>
private string GetUrlWithParameters()
{
if (this.ParameterDictionary == null)
{
return this.Url;
}
if (this.ParameterDictionary.Count == 0)
{
return this.Url;
} var myParameterList = new List<string>();
foreach (var myItem in this.ParameterDictionary)
{
myParameterList.Add(myItem.Key + "=" + myItem.Value);
}
return this.Url + "?" + string.Join("&", myParameterList);
} }
如果客户端是Js,就需要自己组织服务需要的数据了。代码入下所示。
var myFileReader = new FileReader();
var myFileName = ""; myFileReader.onloadend = function () {
var myFileResult = myFileReader.result;
var myFileLength = myFileResult.byteLength; var myFileEntity = new Object()
{
ServerPath: ""
};
Upload(); function Upload() { var myByteArray = myFileResult.slice(0, myFileLength);
var myBlob = new Blob([myByteArray]);
var myFile = new File([myBlob], myFileName);
var myFormData = new FormData();
myFormData.append("file", myFile)
myFormData.append("pEntity", json.stringify(myFileEntity));
request.post(myUrl, {
data: myFormData
}).then(function (data) {
myFileEntity = json.parse(data);
alert("上传文件结束。");
alert(json.stringify(myFileEntity));
}, function (err) {
alert(err);
return;
});
}
} myFileName = this.files[0].name;
myFileReader.readAsArrayBuffer(this.files[0]);
.Net Web API 005 Controller上传小文件的更多相关文章
- Wince 6.0适用 .NET 使用HttpRequest的Post上传文件,服务端的Web API接收Post上传上来的文件 代码
//调用的示例 private string fileName = "InStorageData.csv"; string filePath = parentPath + Comm ...
- SharePoint REST API - 使用REST API和jQuery上传一个文件
博客地址:http://blog.csdn.net/FoxDave 本篇主要通过两个代码示例来展示如何应用REST API和jQuery上传文件到SharePoint. 示例会使用REST接口和j ...
- Windows Azure 系列-- 使用Azure + Web API实现图片上传
1. 创建1个Azure账号,登录之后创建1个AzureStorage.左下方点Manage Access会看到Primary Access Key和Storage Account,记住它们的位置,等 ...
- web api 2.0 上传文件超过4M时,出现404错误
客户端代码 string path = "C:\\text.txt"; WebClient client = new WebClient(); Uri _address = new ...
- C# WEB.API 多图上传
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Ne ...
- windows上在linux客户端上传小文件lrzsz
yum install lrzsz 即可 rz上传,会打开本地图形化界面直接上传 基于centos系统,其他系统请找对应 的源码包编译 一下
- web项目使用fastdsf上传|下载文件
在上传代码中添加一下代码 suffix=suffix.substring(1); fast.FastDFSFile file = new fast.FastDFSFile(mFile.getBytes ...
- Azure VM上传小文件
因为需要传一些脚本到Azure的VM里,有个简单方法可以实现,如下 编辑这个rdp文件 点击确定,连接远程计算机 可以在我的电脑里看到本地硬盘
- webAPI文件上传时文件过大404错误的问题
背景:最近公司有个需求,外网希望自动保存数据到内网,内网有2台服务器可以相互访问,其中一台服务器外网可以访问,于是想在 这台服务器上放个中转的接口.后来做出来以后测试发现没有问题就放线上去了,不顾发现 ...
- Asp.net MVC利用WebUploader上传大文件出现404解决办法。
刚开始我上传小文件都是比较顺利的,但是上传了一个大文件大约有200M的压缩包就不行了.在chrome里面监视发现网络状态是404,我分析可能不是WebUploader的限制,应该是WebConfig限 ...
随机推荐
- 项目打包后配置到node服务器
1.将项目进行打包 npm run build项目根目录下会多出一个打包好的由.js .html .css文件组成的dist文件夹,如图 2.搭建node微型服务器 新建文件夹命名"no ...
- ClickHouse笔记: Ubuntu/Centos下的安装, 配置和用户管理
ClickHouse ClickHouse 属于 OLAP 数据库 OLTP 与 OLAP OLTP (On-Line Transaction Processing 联机事务处理), 注重事务处理, ...
- HCIP- ICT实战进阶ex1-MPLS
HCIP- ICT实战进阶ex1-MPLS 0 前言 由于BGP设备之间是通过TCP协议实现的跨设备互联, 所以在两台BGP设备之间的其他设备是没有配置BGP协议的, 因此中间的其他设备很可能无法学习 ...
- AIGC持续火爆大模型争相推出,庞大市场造就算力供应模式演变
本图由AI生成 黄仁勋说的AI发展迎来iPhone时刻,对NVIDIA有什么影响? 文/王吉伟 近期的AIGC领域仍旧火爆异常. 但火的不只是AIGC应用,还有巨头之间的AI竞赛,以及接连不断上新的A ...
- GPT-4多态大模型研究
1.概述 GPT-4是OpenAI最新的系统,能够产生更安全和更有用的回应.它是一个大型的多模态模型(接受图像和文本输入,输出文本),在各种专业和学术的基准测试中展现了人类水平的表现.例如,它在模拟的 ...
- 基于SqlSugar的开发框架循序渐进介绍(31)-- 在查询接口中实现多表联合和单表对象的统一处理
在一些复杂的业务表中间查询数据,有时候操作会比较复杂一些,不过基于SqlSugar的相关操作,处理的代码会比较简单一些,以前我在随笔<基于SqlSugar的开发框架循序渐进介绍(2)-- 基于中 ...
- 800名科学家Nature联名发文主张废除p值!
每年,全球有数百万学生修读统计学课程.随着世界上的数据量越来越大,统计学已成为越来越受欢迎的话题.如果大多数学生都从这门课中记住一点,那可能就是"统计显著性"和"p 值& ...
- Microsoft Office 2019 官方镜像下载 仅支持Win10系统
Office 2019 专业增强版:(注:这是一个镜像文件) http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d6 ...
- 区块链的Token机制如何理解?
区块链的Token机制如何理解? 为了更好的理解区块链和Token的关系,今天专门基于互联网中的内容,做了下筛选过滤,从而可以让大家更好的理解,对于Token,如果是从事过开发的同学来说,比如容易理解 ...
- JavaCV的摄像头实战之八:人脸检测
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<JavaCV的摄像头实战> ...