.NET Core API如何解码multipart/form-data的图像字符串得到字节数组
问题描述
我正在.NET Core API中尝试从multipart/form-data中提取图像,但是无法确定这段图像数据使用的编码规则,我的目标是获取该字符串所代表的图像字节数组,但目前转换后图像无法正常渲染。
我获取该编码字符串的代码如下:
using (Stream responseStream = resposta.GetResponseStream()) { var contentType = MediaTypeHeaderValue.Parse(response.ContentType); var boundary = HeaderUtilities.RemoveQuotes(contentType.Boundary).Value; for (MultipartReader smth = new(boundary, responseStream); ;) { try { MultipartSection section = await smth.ReadNextSectionAsync(); if (section == null) break; string contentTypeFrame = section.ContentType; // Returns me the encoded string string bodyValue = await section.ReadAsStringAsync(); if (bodyValue.ToLower().Contains("heartbeat")) continue; if (contentTypeFrame == "image/jpeg") { //Do something if it is an image } } catch (Exception ex) { } } }
请问有什么方法可以解码该字符串,得到正确的图像字节数组?
解答
你当前的实现存在逻辑错误,不能对二进制类型的MultipartSection调用ReadAsStringAsync方法,该方法会将原始二进制流按照默认文本编码强制转译为字符串,这个过程会不可逆地损坏二进制数据,你截图中看到的乱码字符串就是损坏后的结果,无法通过解码还原。
正确的实现逻辑如下:
- 调整读取顺序,先判断section的Content-Type,如果是
image/jpeg类型,直接从section的Body流读取二进制数据,不要转成字符串 - 非图像类型的section再读取为字符串,做心跳判断等文本处理
修改后的代码参考:
using (Stream responseStream = resposta.GetResponseStream()) { var contentType = MediaTypeHeaderValue.Parse(response.ContentType); var boundary = HeaderUtilities.RemoveQuotes(contentType.Boundary).Value; var multipartReader = new MultipartReader(boundary, responseStream); MultipartSection section; while ((section = await multipartReader.ReadNextSectionAsync()) != null) { try { string contentTypeFrame = section.ContentType; // 优先处理图像类型,直接读二进制 if (contentTypeFrame == "image/jpeg") { using var memoryStream = new MemoryStream(); await section.Body.CopyToAsync(memoryStream); byte[] imageBytes = memoryStream.ToArray(); // 此处拿到的imageBytes就是可用的JPEG图像字节数组 } else { // 非图像内容才读为字符串处理 string bodyValue = await section.ReadAsStringAsync(); if (bodyValue.ToLower().Contains("heartbeat")) { continue; } // 其他文本类型的业务逻辑 } } catch (Exception ex) { // 建议不要吞异常,添加日志便于排查问题 } } }
补充说明:
- 如果你的业务场景确实需要先读字符串,且确认图像是以Base64编码的字符串形式传递的,可以用
Convert.FromBase64String(bodyValue)转换为字节数组,但你当前截图中的乱码显然不是Base64编码,该方案不适用 - 不要在生产代码中吞掉所有异常,至少添加错误日志,避免出现问题无法定位根因
内容的提问来源于stack exchange,提问作者Pedro Leal
相关产品推荐
相关产品推荐

