C# .NET HttpClient 压缩上传文件和WebApi接受文件解压并使用Dapper保存到数据库

当前环境 .net framework 4.8

如何:压缩和解压缩文件 https://docs.microsoft.com/zh-cn/dotnet/standard/io/how-to-compress-and-extract-files

一开始上传的是byte[], 但是解压的时候总是丢失数据,并且把压缩后的数据流存到MemoryStream也不行,必须在客户端和服务端都保存到真实的文件才可以正常读取。
而且上传的时候要用StreamContent不能用ByteArrayContent.

HttpClient 使用GzipStream压缩文件并上传到WebApi


            try
            {
                string postURL = string.Empty;
                if (this.Config.URL.EndsWith("/"))
                    postURL = this.Config.URL + "Upload/UploadFile?token=" + this.Config.Token;
                else
                    postURL = this.Config.URL + "/Upload/UploadFile?token=" + this.Config.Token;

                foreach (var directoryPath in this.Config.DirectoryPaths)
                {
                    if (!Directory.Exists(directoryPath))
                    {
                        ServiceLog.Log("the path not exists. " + directoryPath);
                        continue;
                    }
                    var currentFiles = Directory.GetFiles(directoryPath);
                    foreach (var fileFullName in currentFiles)
                    {
                        string fileName = string.Empty;
                        try
                        {
                            string contentType = MimeMapping.GetMimeMapping(fileFullName);
                            if (!this.Config.FileTypes.Any(cType => cType == contentType))
                                continue;
                            FileInfo fileInfo = new FileInfo(fileFullName);
                            fileName = fileInfo.Name;
                            var tempCompressFile = Path.GetTempFileName();

                            //compress
                            using (FileStream originalFileStram = fileInfo.OpenRead())
                            {
                                using (FileStream compressedFileStream = new FileStream(tempCompressFile, FileMode.Create, FileAccess.ReadWrite))
                                {
                                    using (var gzipStream = new GZipStream(compressedFileStream, CompressionMode.Compress))
                                    {
                                        originalFileStram.CopyTo(gzipStream);
                                    }
                                }
                            }
                            FileInfo compressFileInfo = new FileInfo(tempCompressFile);
                            var compressFileStream = compressFileInfo.OpenRead();
                            //upload
                            var response = this.UploadFile(postURL, directoryPath, fileName, contentType, compressFileStream);
                            compressFileStream.Close();
                            if (File.Exists(tempCompressFile))
                                File.Delete(tempCompressFile);
                            //move file to new file
                            if (response.IsSuccessStatusCode)
                            {
                                string strUploadFile = Path.Combine(directoryPath, "UploadSuccess");
                                if (!Directory.Exists(strUploadFile))
                                    Directory.CreateDirectory(strUploadFile);
                                string newFilePath = Path.Combine(strUploadFile, fileName);
                                string newFileName = string.Empty;
                                try
                                {
                                    string fileWithoutExt = Path.GetFileNameWithoutExtension(fileFullName);
                                    string fileExtension = Path.GetExtension(fileFullName);

                                    for (int i = 1; i < 65535; i++)
                                    {
                                        if (!File.Exists(newFilePath))
                                            break;
                                        newFileName = string.Format("{0} ({1}){2}", fileWithoutExt, i, fileExtension);
                                        newFilePath = Path.Combine(strUploadFile, newFileName);
                                    }
                                    File.Move(fileFullName, newFilePath);
                                }
                                catch (Exception exMoveFile)
                                {
                                    this.UploadLog(directoryPath, "Copy file failed. {0}, error: {1}", fileName, exMoveFile.Message);
                                }
                                if (!string.IsNullOrEmpty(newFileName))
                                    fileName = string.Format("{0} => {1}", fileName, newFileName);
                                UploadResult resultModel = null;
                                var returnJson = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
                                if (!string.IsNullOrEmpty(returnJson))
                                    resultModel = JsonConvert.DeserializeObject<UploadResult>(returnJson);
                                this.UploadLog(directoryPath, "File Uploaded. {0}, {1}", resultModel?.DocumentID, fileName);
                                continue;
                            }
                            string errorMessage = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
                            if (errorMessage?.Length > 30)
                                errorMessage = errorMessage?.Substring(0, 30);
                            this.UploadLog(directoryPath, "File Upload failed. statusCode: {0}, file: {1}, msg: {2} ", response.StatusCode, fileName, errorMessage);
                        }
                        catch (Exception exx)
                        {
                            this.UploadLog(directoryPath, "File Upload failed. file: {0}, msg: {1} ", fileName, exx.Message);
                        }

                    }
                }
            }
            catch (Exception ex)
            {
                ServiceLog.Log("global exception occurred, service will be exit. " + ex.Message);
            }

        //https://stackoverflow.com/questions/1131425/send-a-file-via-http-post-with-c-sharp
        private HttpResponseMessage UploadFile(string actionUrl, string folder, string fileName, string fileType, Stream fileStream)
        {
            var byteBase64 = System.Text.Encoding.UTF8.GetBytes(folder);
            var base64Folder = Convert.ToBase64String(byteBase64);
            //HttpContent fileNameContent = new StringContent(fileName);
            //HttpContent fileTypeContent = new StringContent(fileType);
            HttpContent folderContent = new StringContent(base64Folder);
            HttpContent streamContent = new StreamContent(fileStream);
            //streamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
            //{
            //    FileName = fileName
            //};
            //streamContent.Headers.ContentType = new MediaTypeHeaderValue(fileType);
            using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                using (var formData = new MultipartFormDataContent())
                {
                    //formData.Add(fileNameContent, "FileName");
                    //formData.Add(fileTypeContent, "FileType");
                    formData.Add(folderContent, "Folder");
                    formData.Add(streamContent, "fileData", fileName);
                    var response = client.PostAsync(actionUrl, formData).GetAwaiter().GetResult();
                    return response;
                }
            }
        }

WebApi接收文件并解压保存至数据库

        [HttpPost]
        public IHttpActionResult UploadFile([Required][FromUri] string token)
        {
            if (token != WebConfig.Token)
                return BadRequest("Token is incorrect");

            var folder = HttpContext.Current.Request.Form["Folder"];
            var bytesFolder = Convert.FromBase64String(folder);
            folder = System.Text.Encoding.UTF8.GetString(bytesFolder);

            var fileStream = HttpContext.Current.Request.Files[0].InputStream;
            var fileName = HttpContext.Current.Request.Files[0].FileName;
            var fileType = HttpContext.Current.Request.Files[0].ContentType;
            byte[] decompressData = null;
            var tempGzFile = Path.GetTempFileName();
            using (FileStream tmpFileStram = new FileStream(tempGzFile, FileMode.Create, FileAccess.ReadWrite))
            {
                fileStream.CopyTo(tmpFileStram);
                fileStream.Flush();
            }
            FileInfo originalFileFinfo = new FileInfo(tempGzFile);

            using (FileStream originalFileStream = originalFileFinfo.OpenRead())
            {
                using (var compressPdfMemory = new MemoryStream())
                {
                    using (GZipStream decompressionStream = new GZipStream(originalFileStream, CompressionMode.Decompress))
                    {
                        decompressionStream.CopyTo(compressPdfMemory);
                        decompressData = compressPdfMemory.ToArray();
                    }
                }
            }
            //Delete Template File
            if (File.Exists(tempGzFile))
                File.Delete(tempGzFile);
            //FileStream destFileStream = new FileStream(@"C:Dataupload" + fileName, FileMode.Create, FileAccess.ReadWrite);
            //destFileStream.Write(decompressData, 0, decompressData.Length);
            //destFileStream.Flush();
            //destFileStream.Close();
            //return Ok();

            var DocumentID = this.Service.UploadToExcDocument(folder, fileName, fileType, decompressData);
            return Ok(new { DocumentID = DocumentID });
        }


        public void UploadToExcDocument(string fileName, string fileType, byte[] fileData)
        {
            string strSql = string.Empty;
            //get DocumentID
            var DocumentID = this.GetKey("DocumentID", this.DatabaseString);
            strSql = @"
INSERT dbo.Document (DocumentName, DocumentSize, ContentType, DocumentDate, Description, DocumentID, DocumentData)
VALUES  (@DocumentName, @DocumentSize, @ContentType, @NowDateTime, '', @DocumentID, @DocumentData);";
            using (SqlConnection conn = new SqlConnection(this.DatabaseString))
            {
                conn.Execute(strSql, new { DocumentID, DocumentName = fileName, ContentType = fileType, DocumentSize = fileData.Length, DocumentData = fileData });
            }
        }
原文地址:https://www.cnblogs.com/grj1046/p/14268628.html