.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限 ...
随机推荐
- Hibernate 基本操作、懒加载以及缓存
前言 上一篇咱们介绍了 Hibernate 以及写了一个 Hibernate 的工具类,快速入门体验了一波 Hibernate 的使用,我们只需通过 Session 对象就能实现数据库的操作了. 现在 ...
- 2021-04-03:给定两个字符串str1和str2,想把str2整体插入到str1中的某个位置,形成最大的字典序,返回字典序最大的结果。
2021-04-03:给定两个字符串str1和str2,想把str2整体插入到str1中的某个位置,形成最大的字典序,返回字典序最大的结果. 福大大 答案2021-04-03: 1.暴力法. 2.DC ...
- Prompt learning 教学[技巧篇]:通过增加示例、引导词、特殊符号指令等方式让chatgpt输出更好的答案
Prompt learning 教学[技巧篇]:通过增加示例.引导词.特殊符号指令等方式让chatgpt输出更好的答案 技巧1:To Do and Not To Do 在问答场景里,为了让 AI 回答 ...
- 百度飞桨(PaddlePaddle) - PaddleOCR 文字识别简单使用
百度飞桨(PaddlePaddle)安装 OCR 文字检测(Differentiable Binarization --- DB) OCR的技术路线 PaddleHub 预训练模型的网络结构是 DB ...
- 顶会ICSE-2023发布LIBRO技术,利用大模型技术进行缺陷重现,自动重现率达33%
摘要:本文围绕LIBRO技术的主要步骤进行介绍. 本文分享自华为云社区<[LLM for SE]顶会ICSE-2023发布LIBRO技术,利用大模型技术进行缺陷重现,自动重现率(33%)实现业界 ...
- 代码随想录算法训练营Day14 二叉树
代码随想录算法训练营 代码随想录算法训练营Day14 二叉树|理论基础 递归遍历 基础知识 二叉树都是通过栈来实现的. 二叉树的种类 在我们解题过程中二叉树有两种主要的形式:满二叉树和完全二叉树. 满 ...
- ENVI5.3 安装教程,新手入门(超详细)附安装包和常见问题
ENVI是一个完整的遥感图像处理平台,广泛应用于科研.环境保护.气象.农业.林业.地球科学.遥感工程.水利.海洋等领域.目前ENVI已成为遥感影像处理的必备软件,包含辐射定标.大气校正.镶嵌裁剪.分类 ...
- 【技术积累】Python中的NumPy库【一】
NumPy库是什么 NumPy是Python科学计算的核心库之一,用来进行科学计算,数值分析等矩阵运算.主要提供了以下几种功能: 1.多维数组(ndarray)对象,可以进行快速的数值计算和数组操作: ...
- Pytorch-如何在模型中引入可学习参数
错误实例: def init(self): self.w1 = torch.nn.Parameter(torch.FloatTensor(1),requires_grad=True).cuda() s ...
- 信创优选,国产开源,Solon v2.3.6 发布
Solon 是什么开源项目? 一个,Java 新的生态型应用开发框架.它从零开始构建,有自己的标准规范与开放生态(历时五年,已有全球第二级别的生态).与其他框架相比,它解决了两个重要的痛点:启动慢,费 ...