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

防止反复造轮子,直接上代码。

客户端代码如下:

csharp 复制代码
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())
                {
                    // 构建上传请求的 Uri
                    string uploadUri = this.textBox2.Text+"/api/File/UploadFolder"; // 替换为你的远程 IIS 服务器地址

                    // 创建 MultipartFormDataContent 用于封装文件内容
                    MultipartFormDataContent content = new MultipartFormDataContent();

                    // 添加压缩后的文件内容到 MultipartFormDataContent
                    byte[] 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代码:

csharp 复制代码
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;
        }
    }
}
csharp 复制代码
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);
                }
            }
        }


      
    }
}

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

过滤器,全局异常捕获:

csharp 复制代码
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中全局注册

csharp 复制代码
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());
        }
    }
}

日志类:

csharp 复制代码
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 MB

        private 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");
                    }
                }
            }
        }

    }
}

工具类:

csharp 复制代码
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;
        }

    }
}
相关推荐
九鼎科技-Leo9 小时前
了解 .NET 运行时与 .NET 框架:基础概念与相互关系
windows·c#·.net
九鼎科技-Leo12 小时前
什么是 ASP.NET Core?与 ASP.NET MVC 有什么区别?
windows·后端·c#·asp.net·mvc·.net
.net开发12 小时前
WPF怎么通过RestSharp向后端发请求
前端·c#·.net·wpf
九鼎科技-Leo16 小时前
在 C# 中,ICollection 和 IList 接口有什么区别?
windows·c#·.net
时光追逐者16 小时前
C#/.NET/.NET Core学习路线集合,学习不迷路!
开发语言·学习·c#·asp.net·.net·.netcore·微软技术
Crazy Struggle19 小时前
.NET 全功能流媒体管理控制接口平台
.net·开源项目·流媒体
.net开发19 小时前
WPF使用prism框架发布订阅实现消息提示
c#·.net·wpf
慧都小妮子1 天前
FastReport将停止 .NET Framework 上的 WebReport 更新
.net·报表控件·fastreport
九鼎科技-Leo1 天前
在 C# 中,如何实现观察者模式?
观察者模式·c#·.net