.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限 ...
随机推荐
- flutter系列之:做一个修改组件属性的动画
目录 简介 flutter中的动画widget AnimatedContainers使用举例 总结 简介 什么是动画呢?动画实际上就是不同的图片连续起来形成的.flutter为我们提供了一个Anima ...
- 分享一个提高运维效率的 Python 脚本
哈喽大家好我是咸鱼,今天给大家分享一个能够提升运维效率的 python 脚本 咸鱼平常在工作当中通常会接触到下面类似的场景: 容灾切换的时候批量对机器上的配置文件内容进行修改替换 对机器批量替换某个文 ...
- RestTemplate发送get请求并携带请求头
//设置请求头 HttpHeaders headers = new HttpHeaders(); headers.add("X-Access-Token", huaWenToken ...
- 文心一言 VS chatgpt (2)-- 算法导论1.2
一.给出在应用层需要算法内容的应用的一个例子,并讨论涉及的算法的功能. 文心一言: 在应用层需要算法内容的应用的一个例子是无人机自主飞行控制.无人机自主飞行控制需要算法来确定无人机的位置.速度和方向, ...
- 2022-05-04:比如,str = “ayxbx“, 有以下4种切法 : a | yxbx、ay | xbx、ayx | bx、ayxb | x, 其中第1、3、4种切法符合:x和y的个数,至少在
2022-05-04:比如,str = "ayxbx", 有以下4种切法 : a | yxbx.ay | xbx.ayx | bx.ayxb | x, 其中第1.3.4种切法符合: ...
- 2021-04-10:给定两个可能有环也可能无环的单链表,头节点head1和head2。请实现一个函数,如果两个链表相交,请返回相交的 第一个节点。如果不相交,返回null。【要求】如果两个链表长度之和为N,时间复杂度请达到O(N),额外空间复杂度 请达到O(1)。
2021-04-10:给定两个可能有环也可能无环的单链表,头节点head1和head2.请实现一个函数,如果两个链表相交,请返回相交的 第一个节点.如果不相交,返回null.[要求]如果两个链表长度之 ...
- 2021-04-03:给定两个字符串str1和str2,想把str2整体插入到str1中的某个位置,形成最大的字典序,返回字典序最大的结果。
2021-04-03:给定两个字符串str1和str2,想把str2整体插入到str1中的某个位置,形成最大的字典序,返回字典序最大的结果. 福大大 答案2021-04-03: 1.暴力法. 2.DC ...
- 2022-02-10:k8s安装mongo,yaml如何写?
2022-02-10:k8s安装mongo,yaml如何写? 答案2022-02-10: yaml如下: apiVersion: v1 kind: Service metadata: labels: ...
- windows server 2012 2019启动 开机自动启动 项设置
1.第一种方法:打开运行功能,运行shell:startup,打开管理员用户启动项目录.将想要设置成开机自启的程序快捷方式添加到其中即可,或者删除其中快捷方式即可取消开机自启.2.第二种方法:打开系统 ...
- 【实践篇】教你玩转JWT认证---从一个优惠券聊起
引言 最近面试过程中,无意中跟候选人聊到了JWT相关的东西,也就联想到我自己关于JWT落地过的那些项目. 关于JWT,可以说是分布式系统下的一个利器,我在我的很多项目实践中,认证系统的第一选择都是JW ...