Multipart/form-data 请求 -- 上传 pdf 导致生成空白文件

Multipart/form-data request -- Uploading pdf is resulting in a blank file

我有一个 objective 可以将 pdf 文件从一台服务器发送到 REST API 来处理一些归档。我正在使用 .NET Core 3.1 和 RestEase API library 来帮助进行一些抽象。

我有一个简单的控制台应用程序,每天在特定时间运行。相关代码如下:

using System;
using System.Linq;
using System.Threading.Tasks;
using RestEase;

namespace CandidateUploadFile
{
    class Program
    {
        static async Task Main(string[] args)
        {
            try
            {
                var apiClientBuilder = new ApiClientBuilder<ITestApi>();
                var api = apiClientBuilder.GetApi("https://my.api.com");
                var candidate = await api.GetCandidateByEmailAddress("tester@aol.com");
                var fileName = "tester.pdf";
                var fileBytesToUpload = await FileHelper.GetBytesFromFile($@"./{fileName}");
                var result = await api.UploadCandidateFileAsync(fileBytesToUpload, candidate.Data.First().Id, fileName);
            }
            catch (Exception e)
            {
                System.Console.WriteLine(e);
            }
        }
    }
}

apiClientBuilder 添加了一些 auth-header,就是这样。我确定那一点不相关。

ITestApi 看起来像这样:

using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Models;
using RestEase;

namespace CandidateUploadFile
{
    public interface ITestApi : IApi
    {
        [Get("v1/candidates/{candidateId}")]
        Task<Models.Response<Candidate>> GetCandidate([Path] string candidateId);

        [Get("v1/candidates")]
        Task<Models.Response<IEnumerable<Candidate>>> GetCandidateByEmailAddress([Query] string email);

        [Get("v1/candidates")]
        Task<Models.Response<IEnumerable<Candidate>>> GetCandidates();

        [Post("v1/candidates/{candidateId}/files?perform_as=327d4d21-5cb0-4bc7-95f5-ae43aabc2db7")]
        Task<string> UploadFileAsync([Path] string candidateId, [Body] HttpContent content);

        [Get("v1/users")]
        Task<Models.Response<IEnumerable<User>>> GetUsers();
    }
}

这里真正相关的是UploadFileAsync

您会从 Program.Main 中注意到我没有明确调用 UploadFileAsync。为了使用 multipart/form-data 请求上传 pdf,我改为调用一个基本包装 UploadFileAsync 的扩展方法。 This approach is what comes as a recommendation in the RestEase library docs.。该扩展方法如下所示:

using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace CandidateUploadFile
{
    public static class ApiExtension
    {
        public static async Task<string> UploadCandidateFileAsync(this ITestApi api, byte[] data, string candidateId, string fileName)
        {
            var content = new MultipartFormDataContent();

            var fileContent = new ByteArrayContent(data);
            fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
            fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
            {
                Name = "file",
                FileName = fileName
            };

            content.Add(fileContent);

            return await api.UploadFileAsync(candidateId, content);
        }
    }
}

那么当我的控制台应用程序执行时会发生什么:我将从上传端点获得成功响应,并且存档服务器上的文件已创建,但它是空白的。

知道 不会 在我发送 .txt 文件时发生这种情况可能很重要。 .txt 文件将保存为预期的内容。

任何见解都会有所帮助。我不知道从哪里开始。

谢谢!

这个问题是由于我在 GetBytesFromFile 静态辅助方法中所做的。

我的静态助手使用 UTF-8 编码对我上传的 .pdf 中的 二进制 内容进行编码。但是,它在我上传的 .txt 文件上运行良好,这是可以预料的。

经验教训:没有必要——也没有意义——在将二进制内容分配给 multipart/form-data 内容之前尝试对其进行编码。我只需要按原样 "pass-through" 二进制内容,或多或少。