- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
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]);
最后此篇关于.NetWebAPI005Controller上传小文件的文章就讲到这里了,如果你想了解更多关于.NetWebAPI005Controller上传小文件的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我有以下正则表达式 /[a-zA-Z0-9_-]/ 当字符串只包含从 a 到z 大小写、数字、_ 和 -。 我的代码有什么问题? 能否请您向我提供一个简短的解释和有关如何修复它的代码示例? //var
我是一名优秀的程序员,十分优秀!