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:\Data\upload" + 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 });
}
}