C# Multipart/Form-Data:为啥 PDF 文件上传没有问题但 JPG 失败?
Posted
技术标签:
【中文标题】C# Multipart/Form-Data:为啥 PDF 文件上传没有问题但 JPG 失败?【英文标题】:C# Multipart/Form-Data: Why do PDF files upload without problems but JPG fail?C# Multipart/Form-Data:为什么 PDF 文件上传没有问题但 JPG 失败? 【发布时间】:2021-11-29 22:46:36 【问题描述】:我有一个要向其发送文件的 RESTFUL API 端点。问题是当我发送 JPEG 文件时,出现问题,Endpoint 无法看到文件。
这是我所知道的:
如果我使用 Fiddler 将 jpeg 文件发送到同一端点,它可以正常工作。 如果我将 pdf 重命名为 rickroll.jpg,则此代码可以正常工作(除了 API 端点确实会失败的图像大小调整,因为它实际上不是 jpg)。我认为这在某种程度上是编码的问题,但我不知道我应该做些什么不同的事情来让它上传 jpeg 文件类型。
private static HttpWebResponse CreateFileUploadRequest(string token)
//Build Upload File API Request [POST]
string url = ConfigurationManager.AppSettings["ApiUrl"] + "api/file/fileupload";
var boundary = "-------------------------acebdf13572468";
var boundaryStartBytes = System.Text.Encoding.ASCII.GetBytes("--" + boundary);
var boundaryEndBytes = System.Text.Encoding.ASCII.GetBytes("--" + boundary + "--");
var contentType = "multipart/form-data; boundary=" + boundary;
//build the outer request
var httpWebRequest = BuildOuterRequest(url, contentType, token);
//add the payload
var fullFilePath = Settings.Instance.FileStoreFolderPath + @"\rickroll.jpg";
var file = File.ReadAllBytes(fullFilePath);
var contentDisposition = System.Text.Encoding.ASCII.GetBytes("\r\nContent-Disposition: form-data; name=\"file\"; filename=\"rickroll.jpg\"\r\n");
var content = System.Text.Encoding.ASCII.GetBytes("Content-Type: image/jpeg\r\n\r\n");
var data = boundaryStartBytes
.Concat(contentDisposition)
.Concat(content)
.Concat(file)
.Concat(boundaryEndBytes).ToArray();
httpWebRequest.ContentLength = data.Length;
//Send the file
using (var streamWriter = httpWebRequest.GetRequestStream())
streamWriter.Write(data, 0, data.Length);
streamWriter.Flush();
streamWriter.Close();
return (HttpWebResponse)httpWebRequest.GetResponse();
服务器会检查以下内容:
var request = HttpContext.Current.Request;
if (request.Files.Count <= 0 || request.Files[0] == null)
throw new ValidationException(Gui.SayApi("You must send a valid File."));
request.Files.Count 在我调试服务器端时显示为 0。
使用 NLOG,这是服务器端的内容
2021-10-11 11:26:11.8197 INFO 6376954837180627849 - Incoming messages:
---------------------------acebdf13572468
Content-Disposition: form-data; name="file"; filename="rickroll.png"
Content-Type: image/jpeg
???? JFIF ?? ;CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 90
?? C
?? C
?? j" ??
?? ? !1AQa"q2???#B??R??$3br?
%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz???????????????????????????????????????????????????????????????????????????
?? ? w !1AQaq"2?B???? #3R?br?
$4?%?&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz?????????????????????????????????????????????????????????????????????????? ? ?S???FM??)??&?\u?3H.:?nM4????@\u?2h????3H.:?nM?.:?nh?q?Srh?.:?nM?.:?nM?.:?nM
[REDACTED ENCODED JPEG]
+?? e????>|%????z??P?W?>???7u*?|?U?O?????T)???a?x??_
??G?i?4m>???,J)v?CF??h(??
O?????C???T????.'??---------------------------acebdf13572468--
2021-10-11 11:26:11.9378 INFO 6376954837180627849 - Outgoing messages:
"Message": "You must send a valid File.",
"Status": "ERROR"
【问题讨论】:
抱歉,这是一个基本问题,但您确定文件对象被填充了吗?您是否使用正确的路径等。 旁注:由于您使用的是 using 语句,因此您无需手动刷新或关闭您的流编写器 - 即使您不需要,close 也会自动刷新 服务器的响应是什么? @ErmiyaEskandary 如果我获取一个 pdf 文件,请将其放入该文件夹并将其重命名为 rickroll.jpg(即使它不是 jpg),服务器端会获取 request.Files.Count = 1它继续处理文件,所以我知道路径是正确的。我修改了原始问题以显示发生了什么以及服务器端 barfs 在哪里的日志。 【参考方案1】:原来我的关闭边界在它前面缺少 CRLF,因此它看起来与编码的 jpeg 是分开的。
var boundaryEndBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--");
我不清楚为什么 PDF 没有这个就没有问题,但 jpeg 和其他文件类型不会上传。
【讨论】:
以上是关于C# Multipart/Form-Data:为啥 PDF 文件上传没有问题但 JPG 失败?的主要内容,如果未能解决你的问题,请参考以下文章
为啥在使用 multipart/form-data 时不能正确发送带有 Unicode 的 POST 名称?
为啥在使用 multipart/form-data 时不能正确发送带有 Unicode 的 POST 名称?
在 c# 中使用 RestClient 作为 multipart/form-data 上传文件
在 c# HttpClient 4.5 中发布 multipart/form-data
C# form表单提交enctype="multipart/form-data" 与 enctype="application/x-www-form-urlencoded