.net web API的文件传输(上传和下载)客户端winform

防止反复造轮子,直接上代码。
客户端代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace FilesClient
{public partial class Form1 : Form{public Form1(){InitializeComponent();}private async void button1_Click(object sender, EventArgs e){// 创建一个 OpenFileDialog 控件并设置相关属性OpenFileDialog openFileDialog = new OpenFileDialog();openFileDialog.Filter = "All Files (*.*)|*.*";openFileDialog.Multiselect = false;需要做c#.net 项目的,有时间并且想赚零花钱的老哥,请加Q群:741058172// 显示文件选择对话框DialogResult dialogResult = openFileDialog.ShowDialog();if (dialogResult == DialogResult.OK){string filePath = openFileDialog.FileName;// 压缩文件string compressedFilePath = CompressFile(filePath);// 创建 HttpClient 对象using (HttpClient client = new HttpClient()){// 构建上传请求的 Uristring uploadUri = this.textBox2.Text+"/api/File/UploadFolder"; // 替换为你的远程 IIS 服务器地址// 创建 MultipartFormDataContent 用于封装文件内容MultipartFormDataContent content = new MultipartFormDataContent();// 添加压缩后的文件内容到 MultipartFormDataContentbyte[] fileBytes = File.ReadAllBytes(compressedFilePath);ByteArrayContent fileContent = new ByteArrayContent(fileBytes);content.Add(fileContent, "file", Path.GetFileName(compressedFilePath));try{// 发送上传请求HttpResponseMessage response = await client.PostAsync(uploadUri, content);// 检查响应状态码if (response.IsSuccessStatusCode){MessageBox.Show("文件上传成功!");}else{MessageBox.Show("文件上传失败!");}}catch (Exception ex){MessageBox.Show("文件上传失败:" + ex.Message);}}// 删除压缩后的临时文件File.Delete(compressedFilePath);}}//采用ZIP压缩算法private string CompressFile(string filePath){string compressedFilePath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + ".zip");using (FileStream originalFileStream = File.OpenRead(filePath)){using (FileStream compressedFileStream = File.Create(compressedFilePath)){using (GZipStream compressionStream = new GZipStream(compressedFileStream, CompressionMode.Compress)){originalFileStream.CopyTo(compressionStream);}}}return compressedFilePath;}private string UploadFolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Downloads");private async void DownloadFile(string fileName){string apiUrl = this.textBox2.Text+"/api/file/DownloadFile?fileName=" + fileName;// 创建文件夹(如果尚未存在)Directory.CreateDirectory(UploadFolderPath);using (HttpClient client = new HttpClient()){HttpResponseMessage response = await client.GetAsync(apiUrl);if (response.IsSuccessStatusCode){using (FileStream fileStream = new FileStream(Path.Combine(UploadFolderPath, fileName), FileMode.Create, FileAccess.Write, FileShare.None)){await response.Content.CopyToAsync(fileStream);}MessageBox.Show("文件下载完成.");}else{MessageBox.Show("下载失败: " + response.ReasonPhrase);}}}private void button2_Click(object sender, EventArgs e){DownloadFile(this.textBox1.Text+ ".zip");}}
}

服务端API代码:

using FileServices.Services;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;namespace FileServices.Controllers
{public class FileController : ApiController{private string UploadFolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UploadFolder");private MediaServer _mediaServer = new MediaServer();[HttpPost]public async Task<IHttpActionResult> UploadFolder(){if (!Request.Content.IsMimeMultipartContent("form-data")){return StatusCode(HttpStatusCode.UnsupportedMediaType);}var provider = new MultipartMemoryStreamProvider();await Request.Content.ReadAsMultipartAsync(provider);await _mediaServer.UploadFolder(provider, UploadFolderPath);// 创建文件夹(如果尚未存在)return Ok();}[HttpGet]public async Task<HttpResponseMessage> DownloadFile(string fileName){// 获取文件路径string filePath = HttpContext.Current.Server.MapPath("~/UploadFolder/" + fileName);// 检查文件是否存在if (!File.Exists(filePath)){return Request.CreateErrorResponse(HttpStatusCode.NotFound, "The specified file does not exist.");}// 创建 HTTP 响应消息HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);// 设置响应内容using (FileStream fileStream = File.OpenRead(filePath)){response.Content = new StreamContent(fileStream);// 设置响应头response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"){FileName = fileName};await response.Content.LoadIntoBufferAsync();}return response;}}
}
using FileServices.Unit;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;namespace FileServices.Services
{public class MediaServer {public async Task UploadFolder(MultipartMemoryStreamProvider provider , string _uploadFolder){// 创建文件夹(如果尚未存在)Directory.CreateDirectory(_uploadFolder);foreach (var content in provider.Contents){var disposition = content.Headers.ContentDisposition;var fileName = disposition.FileName.Trim('"');fileName = IOTools.GetFileName(fileName);var fileData = await content.ReadAsByteArrayAsync();// 将文件保存到本地文件夹中var filePath = Path.Combine(_uploadFolder, fileName);using (var fileStream = new FileStream(filePath, FileMode.Create)){await fileStream.WriteAsync(fileData, 0, fileData.Length);}}}}
}

上传下载代码看上面就够了,

过滤器,全局异常捕获:

using FileServices.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http.Filters;namespace FileServices.Filters
{public class GlobalExceptionHandler : ExceptionFilterAttribute{private static LogServices _logServices = new LogServices();public override void OnException(HttpActionExecutedContext context){// 在这里处理异常,并且返回适当的响应给客户端// 例如,可以记录日志或者返回自定义错误信息// 记录日志LogException(context.Exception);// 返回适当的响应给客户端context.Response = new HttpResponseMessage(HttpStatusCode.InternalServerError){Content = new StringContent("An error occurred, please try again later."),ReasonPhrase = "Internal Server Error"};}private void LogException(Exception exception){// 在这里编写将异常信息记录到日志的代码// 可以使用任何你喜欢的日志库或者自己实现记录日志的逻辑Task.Run(async ()=> {await _logServices.WriteErrorLog(exception.ToString());}).Wait();}}
}

Global中全局注册

using FileServices.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;namespace FileServices
{public class WebApiApplication : System.Web.HttpApplication{protected void Application_Start(){AreaRegistration.RegisterAllAreas();GlobalConfiguration.Configure(WebApiConfig.Register);FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);RouteConfig.RegisterRoutes(RouteTable.Routes);BundleConfig.RegisterBundles(BundleTable.Bundles);// 注册全局异常过滤器GlobalConfiguration.Configuration.Filters.Add(new GlobalExceptionHandler());}}
}

日志类:

using FileServices.Unit;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Web;namespace FileServices.Services
{public class LogServices{public string LogDirectory { get; set; }public string TimeDirName { get; set; }private string LogFileName { get; set; }private const long maxLogSize = 2 * 1024 * 1024; // 2 MBprivate string FirstLogFileName { get; set; }private string newFileName { get; set; }public LogServices(){//在根目录创建Log文件夹IOTools.CreatLogDir("Log");//初始化LogDirectory = Path.Combine(Directory.GetCurrentDirectory(), "Log");TimeDirName = DateTime.Now.ToString("yyyyMMdd");FirstLogFileName = $"log_{DateTime.Now:yyyyMMddHHmmss}.txt";}public async Task WriteErrorLog(string message){await WriteLog("Error", message);}public async Task WriteInfoLog(string message){await WriteLog("Info", message);}public async Task WriteLog(string logType, string message){//创建文件夹string dirType = TimeDirName + "\\" + logType;IOTools.CreatDir(dirType, LogDirectory);LogFileName = Path.Combine(LogDirectory, dirType, FirstLogFileName);if (!File.Exists(LogFileName)){using (StreamWriter sw = File.CreateText(LogFileName)){await sw.WriteLineAsync($"【{logType}{DateTime.Now} \r\n {message}  \r\n \r\n");}}else{FileInfo fileInfo = new FileInfo(LogFileName);if (fileInfo.Length > maxLogSize){string newFileName = $"log_{DateTime.Now:yyyyMMddHHmmss}.txt";FirstLogFileName = newFileName;LogFileName = Path.Combine(LogDirectory, dirType, newFileName);using (StreamWriter sw = File.CreateText(LogFileName)){await sw.WriteLineAsync($"【{logType}{DateTime.Now} \r\n {message}  \r\n \r\n");}}else{using (StreamWriter sw = File.AppendText(LogFileName)){await sw.WriteLineAsync($"【{logType}{DateTime.Now} \r\n {message}  \r\n \r\n");}}}}}
}

工具类:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;namespace FileServices.Unit
{public class IOTools{public static void CreatLogDir(string name){string rootDirectory = Directory.GetCurrentDirectory();CreatDir(name, rootDirectory);}public static void CreatDir(string name, string path){if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("name");if (string.IsNullOrEmpty(path)) throw new ArgumentNullException("path");string logPath = Path.Combine(path, name);// 判断文件夹是否存在if (!Directory.Exists(logPath)){// 在当前项目根目录创建一个新的文件夹Directory.CreateDirectory(logPath);}}public static string GetFileName(string fileName){fileName = fileName.Trim('"');// 如果 fileName 为空,则可以根据需要生成唯一的文件名if (string.IsNullOrEmpty(fileName)){fileName = Guid.NewGuid().ToString();}return fileName;}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/230680.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

conda channel的镜像设置

目录 前言1 显示所有channel2 移除清华镜像3 添加可用的清华源4 下载opencv5 一些其他的conda指令参考文献 ———————————————— 版权声明&#xff1a;本文为CSDN博主「宇内虹游」的原创文章&#xff0c;遵循CC 4.0 BY-SA版权协议&#xff0c;转载请附上原文出处链…

关于“Python”的核心知识点整理大全27

目录 10.5 小结 第&#xff11;1 章 测试代码 11.1 测试函数 name_function.py 函数get_formatted_name()将名和姓合并成姓名&#xff0c;在名和姓之间加上一个空格&#xff0c;并将它们的 首字母都大写&#xff0c;再返回结果。为核实get_formatted_name()像期望的那样工…

arcgis javascript api4.x加载天地图cgs2000坐标系

需求&#xff1a;arcgis javascript api4.x加载天地图cgs2000坐标系 效果&#xff1a; 示例代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"wid…

《LeetCode力扣练习》代码随想录——双指针法(反转字符串---Java)

《LeetCode力扣练习》代码随想录——双指针法&#xff08;反转字符串—Java&#xff09; 刷题思路来源于 代码随想录 344. 反转字符串 相向双指针 class Solution {public void reverseString(char[] s) {if(s.length1){return;}int left0;int rights.length-1;while(left<r…

Python爬虫-解决使用requests,Pyppeteer,Selenium遇到网站显示“您的连接不是私密连接”的问题|疑难杂症解决(2)

前言 本文是该专栏的第13篇,后面会持续分享python爬虫案例干货,记得关注。 相信很多同学在处理爬虫项目的时候,会遇到一些网站出现如下图所示的情况: 就是当你不论是使用requests进行协议请求,还是使用自动化框架pyppeteer或者selenium都会出现上图中的情况。这相信会或多…

查找书籍(缓冲区)

给定n本书的名称和定价&#xff0c;本题要求编写程序&#xff0c;查找并输出其中定价最高和最低的书的名称和定价。 输入格式: 输入第一行给出正整数n&#xff08;<10&#xff09;&#xff0c;随后给出n本书的信息。每本书在一行中给出书名&#xff0c;即长度不超过30的字…

年度大盘点:AIGC、AGI、GhatGPT震撼登场!揭秘人工智能大模型的奥秘与必读书单

这里写目录标题 前言01 《ChatGPT 驱动软件开发》02 《ChatGPT原理与实战》03 《神经网络与深度学习》04 《AIGC重塑教育》05 《通用人工智能》 前言 在2023年&#xff0c;人工智能领域经历了一场前所未有的大爆发&#xff0c;特别是在语言模型领域。新的概念和英文缩写如AIGC、…

Ngnix之反向代理、负载均衡、动静分离

目录 1. Ngnix 1.1 Linux系统Ngnix下载安装 1.2 反向代理 正向代理&#xff08;Forward Proxy&#xff09;&#xff1a; 反向代理&#xff08;Reverse Proxy&#xff09;&#xff1a; 1.3 负载均衡 1.4 动静分离 1. Ngnix Nginx是一个高性能的开源Web服务器&#xff0…

设备运维管理系统,设备列表管理,设备拓扑图关系图,告警日志运维

个人主页&#xff1a; 左本Web3D&#xff0c;更多案例预览请点击》 在线案例 个人简介&#xff1a;专注Web3D使用ThreeJS实现3D效果技巧和学习案例 &#x1f495; &#x1f495;积跬步以至千里&#xff0c;致敬每个爱学习的你。喜欢的话请三连&#xff0c;有问题请私信或者加微…

C# 图解教程 第5版 —— 第19章 枚举器和迭代器

文章目录 19.1 枚举器和可枚举类型19.2 IEnumerator 接口19.3 IEnumerable 接口19.4 泛型枚举接口19.5 迭代器19.5.1 迭代器块19.5.2 使用迭代器来创建枚举器19.5.3 使用迭代器来创建可枚举类型 19.6 常见迭代器模式19.7 产生多个可枚举类型19.8 将迭代器作为属性19.9 迭代器的…

【vSphere | VM】虚拟机自定义规范Ⅳ —— 使用虚拟机自定义规范创建 Linux 和 Windows VM

目录 5. 使用虚拟机自定义规范创建VM5.1 Linux 虚拟机示例Rocky Linux 9.2&#xff08;1&#xff09;克隆虚拟机&#xff08;2&#xff09;模板部署虚拟机 5.2 Windows 虚拟机示例Windows 10&#xff08;1&#xff09;克隆虚拟机&#xff08;2&#xff09;模板部署 Windows 10 …

恒创科技:云服务器怎么买才便宜有优惠

随着云计算技术的不断发展&#xff0c;云服务器已经成为企业和个人用户的重要选择。然而&#xff0c;在购买云服务器时&#xff0c;价格和优惠成为了很多用户关注的焦点。那么&#xff0c;如何购买云服务器才能获得更优惠的价格呢&#xff1f;下面就为大家介绍一些购买云服务器…

windows10-EMQX与MQTTX的安装及配置使用教程

windows10-EMQX安装及配置使用教程 一、下载安装1.1 下载1.2 安装1.3 设置开机自启动 二、连接MQTT2.1 MQTT下载安装2.1.1 下载2.1.2 安装及配置 三、EMQX常用命令 本文介绍的是在windows10系统下的emqx的安装、配置及使用教程。 一、下载安装 1.1 下载 下载链接&#xff1a…

【漏洞复现】金和OA任意文件读取漏洞

Nx01 产品简介 金和数字化智能办公平台&#xff08;简称JC6&#xff09;是一款结合了人工智能技术的数字化办公平台&#xff0c;为企业带来了智能化的办公体验和全面的数字化转型支持。同时符合国家信创认证标准&#xff0c;支持组织数字化转型&#xff0c;实现业务流程的数字化…

订单未支付30分钟自动取消是如何实现的?

1.借助redis的过期特性 下单时&#xff0c;订单状态是待支付。将订单编号作为key&#xff0c;下单的时间戳作为value&#xff0c;设置过期时间是30分钟。服务器监听redis的key过期事件&#xff0c;如果是订单过期&#xff08;还会有其他key过期&#xff09;&#xff0c;则修改…

编程八股文——C/C++中位域概念并示例

位域 C语言允许在一个结构体中以位为单位来指定其成员所占内存长度&#xff0c;这种以位为单位的成员称为“位段”或称“位域”( bit field) 。利用位段能够用较少的位数存储数据。 一个位段必须存储在同一存储单元中&#xff0c;不能跨两个单元。如果第一个单元空间不能容纳…

AI伴侣利用亚马逊云科技机器学习与人工智能服务,加速AI类产品的开发过程

2020年《纽约时报》调查显示&#xff0c;全球有超过1000万人以AI恋人作为伴侣&#xff1b;后浪发布的《2022年轻人未来恋爱白皮书》报告中显示&#xff0c;有近4成年轻人接受与虚拟人恋爱。随着人工智能技术的突破&#xff0c;越来越多年轻群体在AI伴侣软件亲手打造自己的理想恋…

linux查看进程

linux查看进程 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; Linux进程一览&#xff1a;轻松掌握查看进程的技巧 作为一名程序猿&#xff0c;我们常常需要在Lin…

API调试神器!免费IDEA插件推荐

IDEA是一款功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;它可以帮助开发人员更加高效地编写、调试和部署软件应用程序。我们在编写完接口代码后需要进行接口调试等操作&#xff0c;一般需要打开额外的调试工具。 今天给大家介绍一款IDEA插件&#xff1a;Api…

智能优化算法应用:基于风驱动算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于风驱动算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于风驱动算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.风驱动算法4.实验参数设定5.算法结果6.参考文…